使用環境:多線程java程序中。java
做用:在多線程的環境下,控制synchronized代碼段不被多個線程同時執行。synchronized既能夠加在一段代碼上,也能夠加在方法上。多線程
使用:synchronized鎖住的是括號裏的對象,而不是代碼。對於非static的synchronized方法,鎖的就是對象自己也就是this。測試
經過如下兩個案例說明:this
//包含了synchronized 方法的類 public class SynchronizedMethod { public synchronized void test() { System.out.println("線程開始.."); try { Thread.sleep(2000); } catch (Exception e) { e.printStackTrace(); } System.out.println("線程結束.."); } } //測試類 public class MyThread extends Thread{ public void run(){ SynchronizedMethod clazz = new SynchronizedMethod(); clazz.test(); } public static void main(String[] args) { for(int i=0;i<3;i++) { Thread thread = new MyThread(); thread.start(); } } }
執行結果:
線程開始..
線程開始..
線程開始..
線程結束..
線程結束..
線程結束..spa
分析上述執行結果可知:線程
當main方法執行時,分別建立了三個MyThread對象,而這三個對象又各自建立了獨立的 SynchronizedMethred類,雖然使用了test方法使用了synchronized方法修飾,可是synchronized鎖住的是三個獨立的對象,由於三個對象各自分別執行了test方法。code
所以,能夠修改代碼,讓三個線程使用同一個SynchronizedMethod對象:對象
1 //修改測試類代碼以下,使用同一對象調用test方法 2 3 public class MyThread extends Thread{ 4 5 /** 6 * Author:LearnAndGet 7 */ 8 private SynchronizedMethod sync; 9 public MyThread(SynchronizedMethod sync) 10 { 11 this.sync = sync; 12 } 13 14 public void run(){ 15 sync.test(); 16 } 17 18 19 public static void main(String[] args) { 20 SynchronizedMethod sync = new SynchronizedMethod(); 21 for(int i=0;i<3;i++) 22 { 23 MyThread thread = new MyThread(sync); 24 thread.start(); 25 } 26 } 27 }
運行結果:
線程開始..
線程結束..
線程開始..
線程結束..
線程開始..
線程結束..blog
分析上述結果:因爲每次新線程啓動,使用的同一對象sync,所以synchronized生效了。io
固然,更經常使用的方法是:使用schronized鎖住這個類對應的Class對象:
public class SynchronizedMethod { public void test() { //將代碼塊使用synchronized鎖住 synchronized(SynchronizedMethod.class) { System.out.println("線程開始.."); try { Thread.sleep(2000); } catch (Exception e) { e.printStackTrace(); } System.out.println("線程結束.."); } } }
使用上述代碼後,即便每次建立不一樣的SynchronizedMethod對象,執行其test方法時,由於synchronized鎖住了SynchronizedMethod類對應的class對象,因此每次只能有一個SynchronizedMethod的對象獲取鎖,直到該鎖得到釋放,其餘SynchronizedMethod對象都沒法執行其方法。
上述代碼中,經過使用 synchronized(SynchronizedMethod.class)實現了全局鎖的效果
除此以外,使用 static synchronized一塊兒修飾方法時,static方法能夠直接類名加方法名調用,方法中沒法使用this,因此它鎖的不是this,而是類的Class對象,因此,static synchronized方法也至關於全局鎖,至關於鎖住了代碼段。