本篇主要介绍synchronized静态方法和synchronized(class)的使用
1,静态同步方法的锁对象是class不同于静态同步方法的锁对象是类实例
package chapter2.synTwoLock; /* 演示静态方法锁对象和非静态方法锁对象不是同一个锁, 从结果来看ac是异步的,a,b是同步的,因为printa和printb都是静态同步方法,二者锁对象都是class 而printC是非静态的同步方法,锁对象是类实例,和a,b不是一个对象监视器,是异步调用的 线程名称为:a 在 1525529667507 进入printA 线程名称为:c 在 1525529667509 进入printC 线程名称为:c 在 1525529667509 离开printC 线程名称为:a 在 1525529670508 离开printA 线程名称为:b 在 1525529670509 进入printB 线程名称为:b 在 1525529670509 离开printB */ public class Run { public static void main(String[] args) { Service service=new Service(); ThreadA ta=new ThreadA(service); ta.setName("a"); ta.start(); ThreadB tb=new ThreadB(service); tb.setName("b"); tb.start(); ThreadC tc=new ThreadC(service); tc.setName("c"); tc.start(); } } package chapter2.synTwoLock; public class Service { 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) { // TODO Auto-generated catch block 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 chapter2.synTwoLock; public class ThreadA extends Thread { private Service service; public ThreadA(Service service) { super(); this.service=service; } @Override public void run() { super.run(); service.printA(); } } package chapter2.synTwoLock; public class ThreadB extends Thread { private Service service; public ThreadB(Service service) { super(); this.service=service; } @Override public void run() { super.run(); service.printB(); } } package chapter2.synTwoLock; public class ThreadC extends Thread { private Service service; public ThreadC(Service service) { super(); this.service=service; } @Override public void run() { super.run(); service.printC(); } }
2,Class锁可以对类的所有实例起作用
package chapter2.synMoreObjectStaticOneLock; /*演示静态同步方法,对不同类实例的同步效果,也就是Class锁可以对类的所有实例起作用 * a,b线程的service实例是两个不同的对象,但结果是b线程等待a线程结束才会进入静态同步方法, * 如果是非静态的同步方法,不同实例的调用是异步的,这里注意区分 线程名称为:a 在 1525529960193 进入printA 线程名称为:a 在 1525529963193 离开printA //这里等待3s 线程名称为:b 在 1525529963193 进入printB 线程名称为:b 在 1525529963193 离开printB */ public class Run { public static void main(String[] args) { Service service1=new Service(); Service service2=new Service(); ThreadA ta=new ThreadA(service1); ta.setName("a"); ta.start(); ThreadB tb=new ThreadB(service2); tb.setName("b"); tb.start(); } } package chapter2.synMoreObjectStaticOneLock; public class Service { 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) { // TODO Auto-generated catch block 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"); } } package chapter2.synMoreObjectStaticOneLock; public class ThreadA extends Thread { private Service service; public ThreadA(Service service) { super(); this.service=service; } @Override public void run() { super.run(); service.printA(); } } package chapter2.synMoreObjectStaticOneLock; public class ThreadB extends Thread { private Service service; public ThreadB(Service service) { super(); this.service=service; } @Override public void run() { super.run(); service.printB(); } }
3,synchronized(class)
静态方法的synchronized(class)代码块和静态同步方法效果相同package chapter2.synBlockMoreObjectOneLock; public class Service { public static void printA() { synchronized (Service.class) { 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) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void printB() { synchronized (Service.class) { System.out.println( "线程名称为:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + " 进入printB"); System.out.println( "线程名称为:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + " 离开printB"); } } } package chapter2.synBlockMoreObjectOneLock; /*演示静态方法的synchronized(class)代码块和静态同步方法效果相同 线程名称为:a 在 1525530881142 进入printA 线程名称为:a 在 1525530884143 离开printA 线程名称为:b 在 1525530884143 进入printB 线程名称为:b 在 1525530884144 离开printB */ public class Run { public static void main(String[] args) { Service service1=new Service(); Service service2=new Service(); ThreadA ta=new ThreadA(service1); ta.setName("a"); ta.start(); ThreadB tb=new ThreadB(service2); tb.setName("b"); tb.start(); } } package chapter2.synBlockMoreObjectOneLock; public class ThreadA extends Thread { private Service service; public ThreadA(Service service) { super(); this.service=service; } @Override public void run() { super.run(); service.printA(); } } package chapter2.synBlockMoreObjectOneLock; public class ThreadB extends Thread { private Service service; public ThreadB(Service service) { super(); this.service=service; } @Override public void run() { super.run(); service.printB(); } }
参考:<java多线程编程核心技术>