[解決済み] 他のスレッドが終了したかどうかを知るには?
質問
という名前のメソッドを持つオブジェクトがあります。
StartDownload()
というメソッドを持つオブジェクトがあり、3つのスレッドを起動します。
各スレッドの実行が終了したときに通知を受けるにはどうしたらよいでしょうか。
スレッドの1つ(またはすべて)が終了したのか、まだ実行中なのかを知る方法はありますか?
どのように解決するのですか?
いくつかの方法があります。
- 使用する Thread.join() を使用して、各スレッドの完了をブロッキング方式で待ちます。
- チェック Thread.isAlive() を、ポーリング方式で -- 一般的には推奨されません -- 各スレッドが完了するまで待つ、あるいは
- 非正統的な方法で、問題の各スレッドについて、以下のように呼び出します。 setUncaughtExceptionHandler を呼び出す。 を呼び出してオブジェクトのメソッドを呼び、各スレッドが完了したときに捕捉されない例外を投げるようにプログラムするか、あるいは
- のロックやシンクロナイザー、メカニズムを使用する。 java.util.concurrent または
- よりオーソドックスに、メインスレッドにリスナーを作成し、各スレッドが完了したことをリスナーに伝えるようにプログラムします。
アイデア⑤を実装するには? まず、インターフェイスを作成するのが一つの方法です。
public interface ThreadCompleteListener {
void notifyOfThreadComplete(final Thread thread);
}
で、以下のようなクラスを作成します。
public abstract class NotifyingThread extends Thread {
private final Set<ThreadCompleteListener> listeners
= new CopyOnWriteArraySet<ThreadCompleteListener>();
public final void addListener(final ThreadCompleteListener listener) {
listeners.add(listener);
}
public final void removeListener(final ThreadCompleteListener listener) {
listeners.remove(listener);
}
private final void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.notifyOfThreadComplete(this);
}
}
@Override
public final void run() {
try {
doRun();
} finally {
notifyListeners();
}
}
public abstract void doRun();
}
を拡張し、各スレッドは
NotifyingThread
を実装する代わりに
run()
を実装する代わりに
doRun()
. したがって、それらが完了すると、通知を待っている人に自動的に通知されます。
最後に、メインクラス(すべてのスレッド(または少なくとも通知を待っているオブジェクト)を開始するもの)で、そのクラスを次のように修正します。
implement ThreadCompleteListener
に変更し、各スレッドを作成した直後にリスナーのリストに自分自身を追加します。
NotifyingThread thread1 = new OneOfYourThreads();
thread1.addListener(this); // add ourselves as a listener
thread1.start(); // Start the Thread
とすると、各スレッドが終了するときに、あなたの
notifyOfThreadComplete
メソッドは、ちょうど終了した(またはクラッシュした)スレッドのインスタンスで呼び出されます。
なお、より良い方法は
implements Runnable
よりも
extends Thread
に対して
NotifyingThread
のように、Threadを拡張することは通常新しいコードでは推奨されません。 しかし、私はあなたの質問に対してコーディングしています。 を変更すると
NotifyingThread
クラスを実装するために
Runnable
を実装する場合、Threads を管理するコードの一部を変更する必要がありますが、これは非常に簡単なことです。
関連
-
[解決済み】クロススレッド操作が有効でない。作成されたスレッド以外のスレッドからアクセスされたコントロール
-
スレッド "main" で例外発生 java.net.BindException: アドレスは既に使用中です。NET_Bind
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] 整数の平方根が整数であるかどうかを判断する最速の方法
-
[解決済み] Javaで数値を小数点以下n桁に丸める方法
-
[解決済み] Eclipseにプロジェクトをインポートした後に「Must Override a Superclass Method」エラーが発生する。
-
[解決済み] インラインで配列を宣言する方法はありますか?
-
[解決済み] スレッドは何本までならOK?
-
[解決済み】サーブレットはどのように動作するのですか?インスタンス化、セッション、共有変数とマルチスレッド
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
スタイルシートとして解釈されるリソースが、MIMEタイプtext/htmlで転送される。
-
エラーが報告されました。リソースの読み込みに失敗しました:サーバーは500(内部サーバーエラー)のステータスで応答しました。
-
この行に複数のマーカーがある - HttpServletResponseが型エラーに解決できない
-
javaで非静的な解を静的な参照にすることができない
-
コンストラクタの呼び出しは、コンストラクタのエラー理解の最初のステートメントである必要があります。
-
Spring boot runs with Error creating bean with name 'entityManagerFactory' defined in class path resource
-
スレッド "main" で例外発生 java.lang.ArrayIndexOutOfBoundsException: 4 at text.Division.main(Divisi
-
SocketTimeoutExceptionの解決方法です。読み込みがタイムアウトした
-
Exception: java.util.NoSuchElementException: 行が見つかりません
-
テストが見つかりませんでした