Java8で、無限ループを持つワーカースレッドを書こうとしています。
このワーカースレッドはObject.wait()を使って(より正確にはCondition.await()なのですが)イベント発生を待ち順次処理するもので、ワーカースレッドを止めるにはThread.interrupt()を使おうと思っています。
コードの全体像はこんな感じ
java
1void run() 2{ 3 // 初期化 4 5 try 6 { 7 while (Thread.currentThread.isInterrupted()) 8 { 9 synchronized(monitor) 10 { 11 // イベントが存在していたら、処理する 12 13 monitor.wait(); 14 } 15 } 16 } 17 catch (ThreadInterruptedException ignore) 18 { 19 // ワーカースレッド中断を指示された 20 } 21 22 // 後片付け 23}
さてきれいに構造が作れたと思いきや、よく考えたら穴がありました。
「イベントが存在していたら、処理する」を走っているときに外部からinterrupt()が呼ばれると、ThreadInterruptedExceptionは発生しません。そしてそのままmonitor.wait()に突っ込み、最悪無限の待ちに入ってしまいます。さてこれをどうしましょうというのが質問です。
やり方はあると言えばあるのです。
- あくまで脱出条件はフラグ threadContinues なんてのを参照することにし、同期的にこのフラグを制御するようにする。
ちょっと前まではこの方法を必ず使っていました。
でも、Thread.isInterrupted()という道具があるのにわざわざフラグを用意するのが迂遠に感じ始めてなんとかできないかと模索中でして。
- monitor.wait()をmonitor.wait(1000)とすることでisInterrupted()をポーリングする動作にすることでも解決はできます。
ポーリングなのでタイムラグが発生するとかポーリングのたびにCPUが動いちゃうとかで全体的に美しさに欠けますが。
何かこの方式に関して知見をお持ちであればお教えいただければと思います。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/11/18 03:19
2016/11/21 02:20
2016/11/21 03:12
2016/11/21 03:42
2016/11/21 03:54
2016/11/21 04:02
2017/01/20 00:26