[英]Given two Java threads, stop one thread when one of them finishes
我正在為這個問題尋找一個干凈的設計/解決方案:我有兩個線程,可以在用戶想要的時候運行,但最終在用戶發出stop命令時停止。 但是,如果其中一個線程突然結束(例如,由於運行時異常),我想停止另一個線程。
現在兩個線程都執行一個Runnable
(所以當我說'停止一個線程'我的意思是我在Runnable
實例上調用一個stop()方法),我在想的是避免使用線程(Thread類)並使用CompletionService
接口然后將兩個Runnables提交給此服務的實例。
有了這個,我會使用CompletionService的方法take()
,當這個方法返回時,我會停止兩個Runnables,因為我知道它們中至少有一個已經完成。 現在,這有效,但如果可能的話,我想知道一個更簡單/更好的解決方案。
另外,當我們有n
線程時,只要其中一個線程完成停止執行所有其他線程,什么是一個好的解決方案?
提前致謝。
沒有Runnable.stop()
方法,所以這是一個明顯的非首發。
不要使用Thread.stop()
! 在絕大多數情況下,它基本上是不安全的。
如果正確實施,以下是一些應該有效的方法。
您可以讓兩個線程定期檢查一些常見的標志變量(例如,將其stopNow
),並安排兩個線程在完成時設置它。 (標志變量需要是易失性的......或者是正確同步的。)
您可以讓兩個線程定期調用Thread.isInterrupted()
方法以查看它是否已被中斷。 然后每個線程在完成時需要在另一個線程上調用Thread.interrupt()
。
我知道Runnable沒有那個方法,但是我傳遞給線程的Runnable的實現確實有它,並且當調用它時,運行器將完成run()方法(類似於Corsika的代碼,在這個答案之下)。
據我所知,Corsika的代碼假定有一個stop()
方法可以在調用時做正確的事情。 真正的問題是你是如何實現它的? 或者你打算如何實現它?
如果您已經有一個可行的實現,那么您就可以找到問題的解決方案。
否則,我的回答提供了兩種可能的方法來實現“立即停止”功能。
我感謝您的建議,但我有疑問,“定期檢查/致電”如何轉換成代碼?
它完全取決於Runnable.run()
方法執行的任務。 它通常需要在某些循環中添加檢查/調用,以便經常合理地進行測試......但不要太頻繁。 您還想檢查何時可以安全地停止計算,這是您必須自己解決的另一件事。
以下內容應該有助於您了解如何將其應用於您的問題。 希望能幫助到你...
import java.util.*;
public class x {
public static void main(String[] args) {
ThreadManager<Thread> t = new ThreadManager<Thread>();
Thread a = new MyThread(t);
Thread b = new MyThread(t);
Thread c = new MyThread(t);
t.add(a);
t.add(b);
t.add(c);
a.start();
b.start();
c.start();
}
}
class ThreadManager<T> extends ArrayList<T> {
public void stopThreads() {
for (T t : this) {
Thread thread = (Thread) t;
if (thread.isAlive()) {
try { thread.interrupt(); }
catch (Exception e) {/*ignore on purpose*/}
}
}
}
}
class MyThread extends Thread {
static boolean signalled = false;
private ThreadManager m;
public MyThread(ThreadManager tm) {
m = tm;
}
public void run() {
try {
// periodically check ...
if (this.interrupted()) throw new InterruptedException();
// do stuff
} catch (Exception e) {
synchronized(getClass()) {
if (!signalled) {
signalled = true;
m.stopThreads();
}
}
}
}
}
無論您使用停止標志還是中斷,您都需要定期檢查線程是否已發出停止信號。
你可以讓他們互相訪問,或者回訪一下可以訪問兩者的東西,這樣就可以打斷另一個。 考慮:
MyRunner aRunner = new MyRunner(this);
MyRunner bRunner = new MyRunner(this);
Thread a = new Thread(aRunner);
Thread b = new Thread(brunner);
// catch appropriate exceptions, error handling... probably should verify
// 'winner' actually is a or b
public void stopOtherThread(MyRunner winner) {
if(winner == aRunner ) bRunner .stop(); // assumes you have stop on class MyRunner
else aRunner.stop();
}
// later
a.start();
b.start();
// in your run method
public void run() {
// la de da de da
// awesome code
while(true) fork();
// other code here
myRunnerMaster.stopOtherThread(this);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.