对象及变量的并发访问-----synchronized同步(6)-----静态同步synchoronized synchronized(class)代码块的区别
一、将synchronized关键字加到static方法上的时候是给Class类加了锁,而给非static方法加synchronized是给Class类实例的对象加了锁。
创建一个类,其中两个synchronized修饰的静态方法,一个是修饰的非静态方法,将第一个的静态方法sleep3秒,观察两个静态方法的锁,和静态和非静态的锁,如果都是同一个锁,则会发现应该顺序不变,第二三个方法都会等待第一个方法三秒。
实验如下:
创建Service类:
package service; /** * Created by zhc on 2017/10/10 */ public class Service6 { synchronized public static void printA(){ try { System.out.println("线程"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"进入printA"); Thread.sleep(3000); System.out.println("线程"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"离开printA"); }catch (InterruptedException e){ e.printStackTrace(); } } synchronized public static void printB(){ System.out.println("线程"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"进入printB"); System.out.println("线程"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"离开printB"); } synchronized public void printC(){ System.out.println("线程"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"进入printC"); System.out.println("线程"+Thread.currentThread().getName()+"在 "+System.currentTimeMillis()+"离开printC"); } }
三个进程分别调用单个方法:
package extthread; import service.Service6; /** * Created by zhc on 2017/10/10 */ public class Thread1 extends Thread { private Service6 service; public Thread1(Service6 service){ super(); this.service = service; } @Override public void run() { super.run(); service.printA(); } }
package extthread; import service.Service6; /** * Created by zhc on 2017/10/10 */ public class Thread2 extends Thread{ private Service6 service; public Thread2(Service6 service){ super(); this.service = service; } @Override public void run() { super.run(); service.printB(); } }
package extthread; import service.Service6; /** * Created by zhc on 2017/10/10 */ public class Thread3 extends Thread{ private Service6 service; public Thread3(Service6 service){ super(); this.service = service; } @Override public void run() { super.run(); service.printC(); } }
run:
package test; import extthread.Thread1; import extthread.Thread2; import extthread.Thread3; import service.Service6; /** * Created by zhc on 2017/10/10 */ public class Run6 { public static void main(String[] args) { Service6 service = new Service6(); Thread1 t1 = new Thread1(service); t1.setName("A"); t1.start(); Thread2 t2 = new Thread2(service); t2.setName("B"); t2.start(); Thread3 t3 = new Thread3(service); t3.setName("C"); t3.start(); } }
结果:
线程A在 1507622252932进入printA
线程C在 1507622252932进入printC
线程C在 1507622252932离开printC
线程A在 1507622255937离开printA
线程B在 1507622255937进入printB
线程B在 1507622255937离开printB
总结:前四行可以看出,线程C、线程A异步执行,因为两个方法的锁不是一个锁。通过观察方法A、B可以看出来A、B还是相同的锁,所以就算A等了三秒B还是要等A执行完再执行。
浙公网安备 33010602011771号