java多執行緒之鎖機制一
阿新 • • 發佈:2018-11-08
網上看了一篇關於java synchronized關鍵字使用的很好的文章,現將其簡要總結一下,加深理解。
先總結兩個規則:
synchronized鎖住的是括號裡的物件,而不是程式碼。對於非static的synchronized方法,鎖的就是物件本身也就是this。
多個執行緒的synchronized必須鎖住的是同一個物件,才能防止多個執行緒同時執行同一個物件的同步程式碼段。
有兩種方法可以實現多個執行緒鎖住的是同一個物件
1.執行緒中定義相同的成員,成員的值線上程初始化時從外界注入同一個物件。
class Sync { //寫法一 // public void test() { // synchronized(this){ // System.out.println("test開始.."); // try { // Thread.sleep(1000); // } catch (InterruptedException e) { // e.printStackTrace(); // } // System.out.println("test結束.."); // } // } //寫法二,與寫法一等效,都是鎖住物件sync public synchronized void test() { System.out.println("test開始.."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("test結束.."); } } class MyThread extends Thread { private Sync sync; public MyThread(Sync sync) { this.sync = sync; } public void run() { sync.test(); } } public class Main { public static void main(String[] args) { Sync sync = new Sync(); for (int i = 0; i < 3; i++) { Thread thread = new MyThread(sync); thread.start(); } } }
輸出結果:
test開始..
test結束..
test開始..
test結束..
test開始..
test結束..
分析:3個執行緒MyThread中都定義了成員sync,在初始化執行緒時,給每個執行緒的sync賦予了相同的值,即3個執行緒的sync是同一個例項。啟動3個執行緒以後,synchronized鎖住的其實就是this,在當前demo中指的就是sync例項,3個執行緒的sync是同一個物件,所以3個執行緒中使用的同一個物件鎖,同一時刻只能有一個執行緒進入test同步方法塊。
2.使用類對應的Class作為要鎖住的物件,全域性鎖
class Sync { public void test() { synchronized (Sync.class) { System.out.println("test開始.."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("test結束.."); } } } class MyThread extends Thread { public void run() { Sync sync = new Sync(); sync.test(); } } public class Main { public static void main(String[] args) { for (int i = 0; i < 3; i++) { Thread thread = new MyThread(); thread.start(); } } }
輸出結果:
test開始..
test結束..
test開始..
test結束..
test開始..
test結束..
分析:類對應的Class物件作為鎖的目標,確保鎖住的是同一個物件。