2017-10-25 6 views
0

Service.java内のTimeThread.javaの開始 Service.javaが重複して実行されると問題が発生します。複製サービスと同期

なぜ 'isWait'値が 'Log.d( "isRun1")'で 'true'で、 'Log.d( "isRun2")'でfalseですか?

「サービスの重複実行」と「同期」については不思議です。

私のコードは次のとおりです。

Service.java

thread.pauseNrestart(false); 

Thread.java

public class TimeThread extends Thread { 

Handler handler; 
boolean isRun = true; 
boolean isWait = false; 

public TimeThread(Handler handler) { 
    this.handler = handler; 
} 

public void pauseNResume(boolean isWait) { 

    synchronized (this) { 

     this.isWait = isWait; 
      *Log.d("isRun1 :" + isRun + "");* 
     notify(); 
    } 
} 

public void run() { 
    while (isRun) { 
     *Log.d("isRun2 :" + isRun + "");* 
     try { 
      Thread.sleep(1000); 
     } catch (Exception e) { 
      // TODO: handle exception 
     } 
     if (isWait) { 
      try { 
       synchronized (this) { 
        wait(); 
       } 
      } catch (Exception e) { 
       // TODO: handle exception 
      } 
     } 
     handler.sendEmptyMessage(0); 
    } 
} 

}

最適化が行われたときに、コードの

答えて

0

特定の行を並べ替えることがあります。
- コンパイル時にコードを最適化する物事を並べ替えることによって、
- JVMは、物事を並べ替えることによってコードを動的に最適化することができます。
- ハードウェアでは、並べ替えを行うことでパフォーマンスが最適化される場合があります。

ので、コードのセクション:

this.isWait = isWait; 
*Log.d("isRun1 :" + isRun + "");* 

は、行が切り替わっている可能性があります。

これはまた、表示の問題につながる可能性があります。時には他のスレッドから影響が見えなくなることがあります。

whileループをチェックすると、同期セクションには入っていないので、pauseNResumeが別の場所で呼び出された場合、事態が平均して変わる可能性があります。前述したように、これらの変更はスレッドに直ちに表示されないこともあります。

isRunとisWaitをvolatileと宣言してみてください。 Volatileは、その変数への読み書きが再順序付けされないことを保証します。これは、私が指摘した上記のコードセクションの回線が切り替えられた場合の問題を解決するため、isWait変数が変更された後に常に印刷されます。

しかし、whileループ条件のチェックでこれらのブール値を使用する方法では、通常のブール値の代わりにAtomicBooleanも使用することをお勧めします。

+0

「サービスの重複実行」という質問のセクションで尋ねられていることがあまりにもわかりません...私はそれがAndroidと関係するかもしれないと思います - 私のAndroidに関する知識は限られています。上記の答えは、Javaの並行性に関連しています。 – Smiley

+0

私はそれについてもっと考えることができます。あなたの答えをありがとう。 – mmoa

+0

@mmoaあなたの質問が再読されました。 「サービスの重複した実行」が複数のスレッドが実行されていることを意味しているだけです(あなたは「Service.java内でTimeThread.javaを開始しました」)。 1つのスレッドだけでは問題は発生しませんが、2つのスレッドが他のスレッドに影響するものを変更したり、並行性の可視性の問題のために他のスレッドが表示しない変更を加えることがあります。ビジー・ループの代わりに[実行条件](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Condition.html)が役立ち、実行/待機を確認することも可能です – Smiley

関連する問題