在多線程編程中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