示例1:
package com.线程间通信; public class MutiThread1 { private int a = 0; public synchronized void print(String tag){ try { if(tag.equals("a") ){ a = 100; System.out.println("tag a, set number over"); Thread.sleep(1000); }else{ a = 200; System.out.println("tag b set number over"); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("tag "+tag+",a="+a); } public static void main(String[] args) { final MutiThread1 m1 = new MutiThread1(); final MutiThread1 m2 = new MutiThread1(); Thread t1 = new Thread(new Runnable() { public void run() { m1.print("a"); } }); Thread t2 = new Thread(new Runnable() { public void run() { m2.print("b"); } }); t1.start(); t2.start(); } }
这段代码运行出来的结果为:
tag a, set number over tag b set number over tag b,a=200 tag a,a=100 解释:m1和m2是两个不同的对象。m1对象调用print方法,synchronized锁住的对象为m1。而m2对象调用print方法,synchronized锁住的对象为m2。
所以synchronized关键字没有实现锁住同一对象,也就达不到锁的目的了。
示例2:
package com.线程间通信; public class MutiThread1 { private static int a = 0; public static synchronized void print(String tag){ try { if(tag.equals("a") ){ a = 100; System.out.println("tag a, set number over"); Thread.sleep(1000); }else{ a = 200; System.out.println("tag b set number over"); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("tag "+tag+",a="+a); } public static void main(String[] args) { final MutiThread1 m1 = new MutiThread1(); final MutiThread1 m2 = new MutiThread1(); Thread t1 = new Thread(new Runnable() { public void run() { m1.print("a"); } }); Thread t2 = new Thread(new Runnable() { public void run() { m2.print("b"); } }); t1.start(); t2.start(); } } 示例2运行的结果为:
tag a, set number over tag a,a=100 tag b set number over tag b,a=200
解释:示例2代码中,在print方法的前面加上了static关键字,随之变量a也要加上static,这时的print方法是属于MutiThread1对象的。
所以m1调用print方法时,synchronized关键字锁住的对象为MutiThread1。而m2对象调用print方法时,synchronized关键字锁住的对象也为MutiThread1。
这样synchronized锁住的是同一个对象。实现了锁同步。
总结:
关键字synchronized取得的锁都是对象锁,而不是把一段代码(方法)当做锁,所以示例代码中哪个线程先执行synchronized关键字的方法,哪个线程就持有
该方法所属对象的锁(lock),两个对象,线程就是获得的两个不同的锁,他们之间互不影响。
有一种情况是获得相同的锁,即在静态方法上加上synchronized关键字,表示锁定的是.class类,类一级别的锁(独占.class类)