在并发编程中要使用到关键字synchronized
,当咱们用synchronized
关键字修饰一个方法时,表明着一个锁(Lock),那么这个锁的对象是什么,也就是它锁住了谁?编程
synchronized
的使用状况大概就是下面几种:安全
实际上,synchronized修饰非静态方法、同步代码块的synchronized (this)用法和synchronized (非this对象)的用法锁的是对象,线程想要执行对应同步代码,须要得到对象锁。并发
synchronized修饰静态方法以及同步代码块的synchronized (类.class)用法锁的是类,线程想要执行对应同步代码,须要得到类锁。ide
看下面代码:this
public class MultiThread { private static int num = 0; /** static */ public synchronized void printNum(String tag){ try { if(tag.equals("a")){ num = 100; System.out.println("tag a, set num over!"); Thread.sleep(1000); } else { num = 200; System.out.println("tag b, set num over!"); } System.out.println("tag " + tag + ", num = " + num); } catch (InterruptedException e) { e.printStackTrace(); } } //注意观察run方法输出顺序 public static void main(String[] args) { //俩个不一样的对象 final MultiThread m1 = new MultiThread(); final MultiThread m2 = new MultiThread(); Thread t1 = new Thread(new Runnable() { @Override public void run() { m1.printNum("a"); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { m2.printNum("b"); } }); t1.start(); t2.start(); } }
printNum
方法加了synchronized
关键字,根据输入参数不一样打印不一样信息,当咱们执行main
方法时,发现貌似synchronized没起做用。控制台输入以下:线程
tag a, set num over! tag b, set num over! tag b, num = 200 tag a, num = 200
这是由于synchronized
锁住的是对象,线程t1
,t2
分别获取的是m1,m2的锁,他们并无在获取锁上有竞争关系,所以,出现非同步的结果。code
那若是要让printNum
方法在多个对象之间也是线程安全的呢,一个对象在执行这个方法时,其余对象必须阻塞等待,一次只能有一个对象能执行这个方法。只须要加个static
关键字来修饰printNum
方法,这时synchronized
关键字锁住的就是MultiThread
的.class类了。对象
public static synchronized void printNum(String tag) ...
这时的输出结果就符合咱们的预期了同步
tag b, set num over! tag b, num = 200 tag a, set num over! tag a, num = 100