2016-01-05 146 views
0
package indi.JavaLearn; 

public class MultiThread { 
    private static int shared; 
    public static void main(String[] args) { 
     for (int i = 0; i < 5; i++) { 
      (new Thread() { 
       public void run() { 
        write2(); 
       } 
      }).start(); 
     } 
    } 
    public synchronized static void write2() { 
     int i = 0; 
     while (i < 2) { 
      shared++; 
      System.out.println("write," + Thread.currentThread().getId() + "," + String.valueOf(shared)); 
      i++; 
     } 
    } 
} 

結果爲什麼我的多線程執行是單線程模式

write,12,1 
write,12,2 
write,15,3 
write,15,4 
write,16,5 
write,16,6 
write,14,7 
write,14,8 
write,13,9 
write,13,10 
+8

你明白'synchronized'的作用嗎? – MadProgrammer

+0

你能詳細說明問題是什麼嗎?編輯:將方法標記爲synchronized將基本上確保從不同線程執行該方法不會重疊。如果一個線程調用另一個線程仍在執行它,第二個線程將等待,直到第一個線程執行完畢。 –

+0

Java中沒有「單線程模式」這樣的東西。此外,您可以從輸出中看到事件正在同時發生,因爲這些線程執行的順序不正確。 – dimo414

回答

0

你應該閱讀有關Java併發,特別是synchronized關鍵字意味着什麼。

現在,上正在發生的事情與你的代碼...

當一個線程(例如,線程id爲12)調用write2()方法它獲得對象上的鎖(互斥)。然後它執行方法體內的代碼(即循環和打印語句)。最後,它釋放對象上的鎖以允許另一個正在等待執行該方法的線程。因此,您總是可以看到打印語句出現在兩段中。

1

write2中的同步修飾符允許該方法一次只能由一個線程運行 - 您需要刪除它以便同時在多個線程上運行。

如果你真正想要做的是鎖定共享變量,使用​​塊:

synchronized(shared){ 
    shared++; 
    System.out.println("write," + Thread.currentThread().getId() + "," + String.valueOf(shared)); 
} 
0

public synchronized static void write2()是靜態同步方法意味着鎖定/顯示器保持在Class水平,而不是Object水平。

靜態同步方法是​​上的Class對象。如果一個線程正在執行static synchronized方法,則除非通過鎖定線程釋放鎖,否則所有嘗試執行任何static synchronized方法的線程都將被阻止。

非靜態同步方法在this(表示Object,它是類的一個實例)上進行同步。如果一個線程正在執行​​方法,則將阻止嘗試執行任何​​方法on that Object (but not the class)的所有其他線程。

看一看相關SE的問題:

Static versus non-static lock object in synchronized block

What is the difference between synchronized and static synchronized?

您可以在此link

找到有關概念好的文檔

你可能不知道,當一個會發生什麼因爲靜態方法與類關聯,而不是對象,所以調用靜態同步方法。在這種情況下,線程獲取與該類關聯的Class對象的內部鎖。因此,對類的靜態字段的訪問由與該類的任何實例的鎖截然不同的鎖來控制。