2009-07-16 12 views
-2

私は私が期待どおりに動作しない同期化の問題を抱えているが、私はまた、揮発性のキーワードを使用してみました: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

「リビアでのスレッドリベリアの素晴らしいこと」をどのように期待できますか?あなたのプログラムには "awesome"という単語は含まれていません –

答えて

1

がある間

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

はその後の進路2つのスレッドがインターレースかもしれない2ライナー別途getValueへのアクセスとsetValueを同期しています続き:

  1. スレッド1組の値
  2. スレッド2組の値
  3. スレッド1がスレッド2

によって設定された値は、この問題を解決するためには、あなたが/取得を守る1つのロックオブジェクトを持っている必要があります読み込みset関数は両方のスレッドを呼び出します。これを行う最善の方法は、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

は1つだけのは、何が起こるsetValuegetValue