まず、Threadクラスの可能な状態から始めます。
Enum Thread.State
NEW:6つの可能な状態がありますまだ開始されていないスレッドがこの状態にあります。
RUNNABLE:Java仮想マシンで実行中のスレッドは、この 状態です。
ブロック:モニタロックを待機しているブロックが にあります。
待ち:別のスレッドを無期限に待機しているスレッド は、この状態です。
TIMED_WAITING:別のスレッドが実行するのを待機しているスレッド 指定された待機時間までの動作はこの状態です。
TERMINATED:終了したスレッドはこの状態です。
あなたが「終了」状態にあると言ったように「殺された」スレッド。 Terminated状態につながる主な原因は2つあります。
- A)run()メソッドは正常に終了した後に終了します。
- B)例外が発生し、run()メソッドが終了しました。
スレッドを「決して」終了モードにしたい場合は、A)無限ループを持つべきです。B)すべての例外をキャッチする必要があります。しかし、それはまさにあなたの質問ではありませんでした。どのようにスレッドの状態を監視するには?
キーがgetState()方法
このスレッドの状態を返します
公共Thread.State getStateを()
です。このメソッドは、同期制御ではなくシステム状態の監視に使用するように設計されています。
あなたは、次の3つのクラスであなたがやりたいことができます。
package com.what.ever;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class App {
private static int MONITORING_FREQUENCY = 5;
private static int NUMBER_OF_TASKS = 3;
public static void main(String[] args) {
List<ThreadMonitor> threadMonitors = initThreadMonitors();
threadMonitors.forEach(m -> m.printState());
threadMonitors.forEach(m -> m.startThread());
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(() -> threadMonitors.forEach(m -> m.restartIfTerminated()), MONITORING_FREQUENCY, MONITORING_FREQUENCY, TimeUnit.SECONDS);
}
private static List<ThreadMonitor> initThreadMonitors() {
List<ThreadMonitor> threadMonitors = new ArrayList<>();
for (int i = 1; i <= NUMBER_OF_TASKS; i++) {
DummyRunnable runnable = new DummyRunnable(i);
ThreadMonitor threadMonitor = new ThreadMonitor(runnable);
threadMonitors.add(threadMonitor);
}
return threadMonitors;
}
}
ThreadMonitor.java
package com.what.ever;
public class ThreadMonitor {
private Thread thread;
private DummyRunnable runnable;
public ThreadMonitor(DummyRunnable runnable) {
this.runnable = runnable;
this.thread = new Thread(runnable);
}
public boolean startThread() {
boolean isStarCalled = false;
if(Thread.State.NEW.equals(thread.getState())) {
thread.start();
isStarCalled = true;
}
return isStarCalled;
}
public void printState() {
System.out.println(thread.toString() + " is in state : " + thread.getState());
}
public void restartIfTerminated() {
printState();
if(Thread.State.TERMINATED.equals(thread.getState())) {
thread = new Thread(runnable);
thread.start();
}
}
}
DummyRunnable.java
package com.what.ever;
public class DummyRunnable implements Runnable {
private int id;
public DummyRunnable(int id) {
this.id = id;
}
public void run() {
System.out.println("Runnable " + id + " started in thread: " + Thread.currentThread());
dummyWork();
System.out.println("Runnable " + id + " done");
}
private void dummyWork() {
int sleep = 10000;
if (id == 3) {
sleep = 1000;
}
try {
Thread.sleep(sleep);
} catch (Exception e) {
System.out.print(e);
}
}
}
App.java
ここに行きます。この例について質問がある場合は、尋ねてください。
小さな警告: 監視頻度に注意してください。パフォーマンスに大きな影響を与える可能性があります。これでリアルタイムアプリケーションを実行しようとしないでください。
スレッドが停止していないことを確認するのはどうでしょうか?スローされた 'Exception'を'試行 '/' catch'します。 –
この記事では、スレッドが停止したときに通知を受け取るためにカスタムリスナーを使用しています。http://www.algosome.com/articles/knowing-when-threads-stop.html – Berger
@Andy Turnerスレッドが停止できる唯一の方法はJavaコードの例外ですか?スレッドを監視し、それらのどれかがメインクラスから生きているかどうかを確認できますか? – user3608212