2011-08-01 11 views
0

私は、Javaのマルチスレッドでいくつかの問題を持つ最良の例で説明しています:のJavaマルチスレッドの同期の問題

class Thread1 extends Thread 
    { 
     boolean val=false; 


     public void set() 
     {  
      val=true; 
     } 


     public void run() 
     { 

     while (true) 
     { 

      if(val==true) 
      { 
       System.out.println("true"); 
       val=false; 
      } 

      try 
      { 
       sleep(1); 
      } 
      catch (InterruptedException e) 
      { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

    } 
} 

だから、これは別のスレッドで実行される単純なクラスです。

今、この場合考える: 1)私はThread1.set()機能 3呼び出す他のスレッドから) 2以上のクラスのスレッドを開始する)Thread1.run()関数の条件が真

に評価

ここで、上記のコードからsleep(1)を削除すると、この条件は決してtrueに設定されません。

私の質問は、 他の関数がrun()関数内で使用される変数を設定できるようにrun()関数を中断できる方法はありますか? (私はAndroid上でゲームを作っています。そのため、OpenGLレンダラーは1つのスレッドで実行され、ゲームロジックスレッドは別のスレッドで実行され、1フレームまたは2フレームごとに同期させたいと思います)

答えて

4

スレッド(それを読み取るスレッド以外のスレッド)はvalを変更してからvolatileにします。

+0

はい、これをvolatileにすることは、多くの解決策の1つに過ぎませんが、なぜこれが実際に動作するのか、そしてthread.sleep()が結果に何らかの影響を与える理由を説明することができます。 –

+0

私は揮発性の部分を説明することができます。 'volatile'は2つのスレッド間で' synchronizes-with'関係を確立します。スレッドT1がスレッドT2が揮発性変数に書き込んだ値を見ると、T1は不揮発性変数を含む以前のすべての書き込みをT2が参照することが保証されます。私はすでに、T1がそれを読み込もうとする前にT2が揮発性変数に書き込むと、T1は常にT2によって書き込まれた値を読み込むと言いましたが、これは真実ではないと私は思っています。 )。 「睡眠」の影響については、私を打つ! –

3

ブール変数がvolatileではないため、2つの異なるスレッドが同じ値を見ているという保証はありません。スリープ状態にすると、仮想マシンによって、別のスレッドから設定された値がスレッドに見えるようになることがあります(これは何も推測ではありません)。しかし、この動作は決して信頼されるべきではありません。必要に応じてvolatileブール変数またはAtomicBooleanクラスを使用する必要があります。

+0

これでうまくいくはずです、ありがとう! – n3XusSLO