synchronized關鍵字

在多線程編程中synchronized一直是元老級的角色,不少人稱呼它爲重量級鎖。Java6以後爲了減小得到鎖和釋放鎖帶來的性能消耗引入了偏向鎖和輕量級鎖,對synchronized進行了各類優化,它變得不那麼重了。java

synchronized實現同步的基礎是:Java中的每個對象均可以做爲鎖。
具體見如下四種形式,其中1,2屬於同一類,都是對一個普通的對象加鎖,3,4屬於同一類,都是對類的class對象加鎖。編程

  • 對於普通同步方法,鎖是當前實例對象,即this。
  • 對於同步方法塊,鎖是synchronized括號裏配置的對象,這個對象也能夠是this。
  • 對於靜態同步方法,鎖是當前類的class對象。
  • 對於靜態同步方法塊(synchronized括號裏是類的class對象),和第三種狀況同樣,鎖是當前類的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

相關文章
相關標籤/搜索