此處用一個小程序來說明一下,邏輯是一個計數器(int i);主要的邏輯功能是,如果同步監視了資源i,則不輸出i的值,但如果沒有添加關鍵字synchronized,因為是兩個線程并發執行,所以會輸出i的值,類實現Runnable接口。
下面是run()方法,利用i一次加二,若是奇數則輸出,若輸出(則為并發編程,共享資源沒有被監視),若沒有輸出(則共享資源被監視,一次只允許一個線程使用),Runnable接口的Run方法如下所示:
public void run(){ while(true){ if(this.getValue()%2!=0){ System.out.PRintln(this.getValue()); } if(Thread.currentThread().getName().equals("b")){ this.next(); } try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }在分別寫一個得到i值的方法,和增加i值的方法,若是同步監視的并發線程要加synchronized,若不是可不加,自行比較結果:
public synchronized void next(){ //此處的synchronized,定義了此處代碼塊,只允許一個線程訪問 i+=2;//i一次性加二 } public synchronized int getValue(){ return i; }//得到i的值,進行輸出判斷在類中創建一個主方法,構造一個對象,實例化兩個線程,補充一點,synchronized關鍵字修飾的代碼塊,只允許同一個對象的不同線程至多一次訪問,而如果構造了兩個對象那么synchronized修飾的代碼塊,依然會被同時訪問,容易造成數據混亂,死鎖的現象。
代碼如下:
public static void main(String[] args){ SecondThread st = new SecondThread(); Thread st1 = new Thread(st,"a"); Thread st2 = new Thread(st,"b"); st1.start(); st2.start(); try { st1.join(); st1.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }輸出為(無輸出,且線程不銷毀):
若是去除掉synchronized,能輸出奇數。
新聞熱點
疑難解答