對于線程,在實際應用中我用的并不多,關鍵在于對線程的使用不是特別熟悉,現在抄個例子來復習復習。例子如下:





















































上面的例子中,print出來的4句代碼先后順序是怎樣的呢?
是:
in staticB() : inside sync block
leaving staticB() : outside sync block
entering staticA()
leaving staticA()
in staticB() : inside sync block
entering staticA()
leaving staticB() : outside sync block
leaving staticA()
其實,上面的兩種可能都有。
先利用代碼上復習下線程中的靜態方法同步。
方法:staticA是一個靜態方法,同時,也是一個同步方法。那說明對方法staticA同步即同步的是StaticBlock類。
staticB中使用了對StaticBlock類進行同步,也就是說,如果StaticBlock被調用了那么同步段的代碼將不會立即執行,只有等到同步的StaticBlock類解鎖后才會執行。并且執行的時候還會對StaticBlock這個類上鎖。
由于方法staticB中同步塊并沒有包含“System.out.println("leaving staticB() : outside sync block");”這句代碼。那也就是說,這句print代碼并不在同步范圍內。
結合例子來看,main方法中首先run的是threadB,這個時候StaticBlock類并沒有被同步,因此,System.out.println("in staticB() : inside sync block");這句代碼將被立即執行,接下來是sleep2秒鐘,這時候main方法中的threadA也開始執行了。threadA訪問的是靜態同步方法staticA。這時候,靜態同步方法被同步的是當前的這個類StaticBlock,由于staticB方法中同步塊還在執行(因為2秒的sleep還未結束),因此threadA調用staticA方法還需等待。
當staticB中的同步塊執行完了以后,staticA方法會馬上被調用。這時候是staticA中的System.out.println("entering staticA()");先執行還是staticB中的System.out.println("leaving staticB() : outside sync block");先執行,這個就看運氣了。兩個都有可能先執行。
如果要staticB方法中的System.out.println("leaving staticB() : outside sync block");先執行,那么就可以將此句代碼放入同步塊中。
從這個例子中也可以看出:
1、線程同步必然是有多個線程在同時運行。
2、需要同步是因為多個線程在爭搶資源。
3、需要被同步的是共享的資源,也就是多個線程爭搶的。
4、對靜態方法同步其實就是對當前類進行同步。