本篇介绍synchronized(非this对象x)方式的同步,x一般是参数或者实例变量
不同线程持有不同的对象监视器,调用是异步的
package chapter2.synBlockString3; /*演示不同线程持有不同的对象监视器,调用是异步的 * ta的对象监视器是anyString,而b的对象监视器是类实例对象 a begin b begin b end a end */ public class Run { public static void main(String[] args) { Service service=new Service(); ThreadA ta=new ThreadA(service); ThreadB tb=new ThreadB(service); ta.setName("a"); ta.start(); tb.setName("b"); tb.start(); } } package chapter2.synBlockString3; public class Service { private String anyString=new String(); public void a(){ try{ synchronized (anyString) { System.out.println("a begin"); Thread.sleep(3000); System.out.println("a end"); } }catch(InterruptedException e){ e.printStackTrace(); } } synchronized public void b(){ System.out.println("b begin"); System.out.println("b end"); } } package chapter2.synBlockString3; public class ThreadA extends Thread{ private Service service; public ThreadA(Service service) { this.service=service; } @Override public void run() { super.run(); service.a(); } } package chapter2.synBlockString3; public class ThreadB extends Thread{ private Service service; public ThreadB(Service service) { this.service=service; } @Override public void run() { super.run(); service.b(); } }
synchronized(非this对象x)用法的三个结论:
1,当多个对象同时执行synchronized(x){}同步代码块时呈同步效果
2,当其他对象执行x对象的synchronized方法时呈现同步效果,但如果其他线程调用x对象的非synchronized方法还是异步的
3,当其他对象执行x对象里的synchronized(this)代码块时也是同步的
前两条结论比较明显,仅仅验证第三条结论:
package chapter2.test3; public class MyObject { public void speedPrintString(){ synchronized (this) { System.out.println("speedPrintString __get locked time="+System.currentTimeMillis()+ "run thread name="+Thread.currentThread().getName()); System.out.println("------------------"); System.out.println("speedPrintString ___release locked time="+System.currentTimeMillis()+ "run thread name="+Thread.currentThread().getName()); } } } package chapter2.test3; /*演示当使用syn(obj)方式时,其他进程进入obj的syn(this)代码块是同步的,因为syn(this)也是对obj实例加锁 * 也就是b线程需要等待a线程执行完syn(obj),释放obj的锁,才能获得obj的锁, testMethod1 _____get locked time=1525528023801run threadName=a testMethod1 _____release locked time=1525528025801run threadName=a speedPrintString __get locked time=1525528025801run thread name=b ------------------ speedPrintString ___release locked time=1525528025802run thread name=b */ public class Run { public static void main(String[] args) throws InterruptedException { Service sv=new Service(); MyObject mo=new MyObject(); ThreadA ta=new ThreadA(mo, sv); ThreadB tb=new ThreadB(mo); ta.setName("a"); ta.start(); //这里将main线程睡眠是为了让a线程先进入同步块 Thread.sleep(100); tb.setName("b"); tb.start(); } } package chapter2.test3; public class Service { public void testMethod1(MyObject obj){ synchronized (obj) { try{ System.out.println("testMethod1 _____get locked time="+System.currentTimeMillis()+ "run threadName="+Thread.currentThread().getName()); Thread.sleep(2000); System.out.println("testMethod1 _____release locked time="+System.currentTimeMillis()+ "run threadName="+Thread.currentThread().getName()); }catch(InterruptedException e){ e.printStackTrace(); } } } } package chapter2.test3; public class ThreadA extends Thread { private MyObject obj; private Service sv; public ThreadA(MyObject obj,Service sv) { super(); this.obj=obj; this.sv=sv; } @Override public void run() { super.run(); sv.testMethod1(obj); } } package chapter2.test3; public class ThreadB extends Thread { private MyObject obj; public ThreadB(MyObject obj) { super(); this.obj=obj; } @Override public void run() { super.run(); //调用obj的syn方法 obj.speedPrintString(); } }
参考:<java多线程编程核心技术>