2009-07-16 149 views
-2

我在與同步行爲不我所期望的方式問題,我嘗試使用volatile關鍵字也:的Java同步和線程

共享對象

public class ThreadValue { 

    private String caller; 
    private String value; 

    public ThreadValue(String caller, String value) { 
     this.value = value; 
     this.caller = caller; 
    } 

    public synchronized String getValue() { 
     return this.caller + "  " + this.value; 
    } 
    public synchronized void setValue(String caller, String value) { 
     this.caller = caller; 
     this.value = value; 
    } 
} 

主題1:

class CongoThread implements Runnable { 
    private ThreadValue v; 
    public CongoThread(ThreadValue v) { 
     this.v = v; 
    } 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      v.setValue("congo", "cool"); 
      v.getValue(); 
     } 
    } 
} 

螺紋2:

class CongoThread implements Runnable { 
    private ThreadValue v; 
    public CongoThread(ThreadValue v) { 
    this.v = v; 

    } 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      v.setValue("congo", "lame"); 
      v.getValue(); 
     } 
    } 
} 

調用類:

class TwoThreadsTest { 
    public static void main (String args[]) { 

     ThreadValue v = new ThreadValue("", ""); 
     Thread congo = new Thread(new CongoThread(v)); 
     Thread libya = new Thread(new LibyaThread(v)); 

     libya.start(); 
     congo.start(); 
    } 
} 

偶爾我得到"In Libya Thread congo cool" 這絕不應該發生。我只希望:
"In Libya Thread libya awesome"
"In Congo Thread congo cool"

我不希望他們進行混合。

+1

你怎麼能期待「在利比亞螺紋利比亞真棒」?你的程序不包含「真棒」 – 2009-07-16 05:30:25

回答

1

會發生什麼事是以下爲:

  1. 線程1設定值
  2. 線程2套價值
  3. 線程1讀取由線程2

設置爲了解決這個問題,你需要的價值有守衛GET 1個鎖定對象/設置函數調用這兩個線程。做到這一點的最好方法是創建一個同時執行set和get的額外同步方法。但有時候這是不可取的。在這種情況下,給兩個線程一個鎖對象。這只是一個普通的對象。然後它們在一個同步塊中使用。

每個線程的實現都像下面這樣,注意它們需要有完全相同的對象!

Object lockObject = new Object(); 
Thread t1 = new CongroThread(v, lockObject); 
Thread t2 = new LibyaThread(v, lockObject); 

... 

class CongoThread implements Runnable { 
    private ThreadValue v; 
    private Object lockObject; 

    public CongoThread(ThreadValue v, Object lockObject) { 
    this.v = v; 
    this.lockObject = lockObject, 
    } 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      synchronized(lockObject) 
      { 
       v.setValue("congo", "lame"); 
       v.getValue(); 
      } 
     } 
    } 
} 
0

您是否同步System.out.print調用?沒有同步,它們是線程安全的,但不能以正確的順序發射。

synchronzied(System.out) { 
    System.out.print(....); 
    System.out.flush(); 
} 
1

你只是同步訪問getValuesetValue分別是這兩個內膽

v.setValue("congo", ..); 
v.getValue(); 

當然然後兩個線程可以交錯之間一個的setValuegetValue