在多线程编程中synchronized一直是元老级的角色,不少人称呼它为重量级锁。Java6以后为了减小得到锁和释放锁带来的性能消耗引入了偏向锁和轻量级锁,对synchronized进行了各类优化,它变得不那么重了。java
synchronized实现同步的基础是:Java中的每个对象均可以做为锁。
具体见如下四种形式,其中1,2属于同一类,都是对一个普通的对象加锁,3,4属于同一类,都是对类的class对象加锁。编程
当一个线程试图访问同步代码块时,它首先必须获得锁,退出或抛出异常时就会释放锁。多线程
下面对第四种状况作一个演示:ide
class ServiceObj{ public void doService() { synchronized (ServiceObj.class) { System.out.println(Thread.currentThread().getName()+"的业务方法开始"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"的业务方法结束"); } } } class MyThread extends Thread{ private ServiceObj serviceObj; public MyThread(ServiceObj serviceObj) { super(); this.serviceObj=serviceObj; } @Override public void run() { serviceObj.doService(); } } public class SynchTest { public static void main(String[] args) { ServiceObj serviceObj0 = new ServiceObj(); MyThread myThread0 = new MyThread(serviceObj0); myThread0.start(); ServiceObj serviceObj1=new ServiceObj(); MyThread myThread1=new MyThread(serviceObj1); myThread1.start(); } }
输出结果以下:性能
Thread-0的业务方法开始 Thread-0的业务方法结束 Thread-1的业务方法开始 Thread-1的业务方法结束
能够看到两个线程保持同步。优化
但若是咱们把synchronized括号里的内容改一下,变为状况二:this
synchronized (this)
输出结果就不一样步了,以下:线程
Thread-0的业务方法开始 Thread-1的业务方法开始 Thread-1的业务方法结束 Thread-0的业务方法结束
由于一个是对类加锁,另外一个是对对象加锁。code