[英]How to kill a thread nice in java?
一個常見的問題,但我沒有找到任何可接受的答案。
我最近遇到了如何以一種很好的方式殺死一個線程的問題。 我嘗試創建一個接受runnables的通用消息處理程序。 問題是我無法以足夠快的速度退出當前的runnable。
runnables中的代碼是未知的,即jni,純java,3:rd部分lib等。下面是一個簡單的例子,睡眠“鋼化”中斷所以線程永遠不會退出(足夠快):我不能夠在任何時候中斷線程,只在每個任務之間是不可接受的。 我的第一個想法是使用thread.stop但不推薦使用。
制片人:
int i = 0;
MessageHandler handler = new MessageHandler();
handler.start();
handler.post(new Runnable() {
@Override
public void run() {
System.out.println("task -" + i++ + " " + Thread.currentThread().getName());
for (int r=0;r<1000000000;r++) {
System.out.println("task -" + i++ + " " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
try {
Thread.sleep(500);
} catch (InterruptedException q) {
q.printStackTrace();
}
handler.interrupt();
消費者(MessageHandler):
package test;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class MessageHandler extends Thread implements Runnable {
private BlockingQueue<Runnable> msgQue = new LinkedBlockingQueue<Runnable>();
private final static String TAG = "MessageHandler";
public void run() {
try {
System.out.println(TAG + " Initialized " + currentThread().getName());
while(true) {
Runnable task = msgQue.take();
task.run();
if (isInterrupted()) {
break;
}
}
} catch (InterruptedException e) {
System.out.println(TAG + " InterruptedException " + currentThread().getName());
} finally {
System.out.println(TAG + " Exit " + currentThread().getName());
msgQue.clear();
msgQue = null;
}
}
public void post(Runnable task) {
System.out.println(TAG + " post " + currentThread().getName());
msgQue.add(task);
}
}
我覺得自己就像一個沒有任何超能力的超人......
嘿,甲骨文給了我力量!
看看這個常見問題解答他們為什么棄用Thread.stop()
以及改為使用什么。 它的要點是使用Thread.interrupt()
。
不,JVM沒有安全的方法來終止任意線程。 請參閱有關這些問題的討論:
我通過使用守護進程解決了這個問題(“一個線程是守護進程”意味着一旦它的父威脅結束就會被終止):我創建了一個可運行的類來控制所需的runnable類。
class Interruptable implements Runnable {
private Threat t;
public Interruptable(Threat t) {
this.t = t;
this.t.setDeamon(true); //this is the important line
}
public void run() {
this.t.start();
while(true) {
try {
Thread.sleep(1);
}
catch(InterruptedException ex) {
break;
}
}
}
}
現在,當可中斷線程結束時(通過調用中斷方法)子威脅如果被終止也是因為它是一個守護進程。
PS:我不知道怎么寫威脅或線程,我懶得去谷歌:)
您可以停止或中斷線程,這兩種解決方案都不是完美的:
InterruptedException
,必須明確捕獲)。 因此,如果一個線程沒有檢查他的中斷狀態,它可能會一直運行。 一般來說,1被認為更糟糕,所以這就是它被棄用的原因。
如何解決困境沒有理想的方法。 要么中斷線程以使它們正常退出,然后它們可以忽略中斷,或者你突然終止它們,然后就不能進行清理。
一種可能性如何以某種方式獲得兩者的最佳效果是中斷線程,等待幾秒鍾,然后突然停止它。 但我不推薦它,停止只是不安全。
另一種可能性是在單獨的進程中啟動任務。 這很復雜,您需要配置可執行路徑,不同平台可能表現不同等等。但是這些流程將完全獨立於您的應用程序,您可以安全地終止它們並讓操作系統進行所有必要的清理。
通過您嘗試停止的代碼的合作,您可以使用您想要的任何機制來完成它。 如果沒有該代碼的合作,停止一個線程將無濟於事。 如果該線程與其他線程協調怎么辦? 如果那個線程導致真正的工作完全在另一個進程中完成怎么辦?
這確實是一個乏味的問題。 我可能會因為我要說的而被投票,但我相信這種對Thread.stop
恐懼有時候並不存在。
既然你提到你知道要停止的代碼是做什么的,那么如果你能確定,如果突然停止,它就不會留下任何懸掛資源(文件,套接字等),不會導致任何形式數據損壞或不會導致任何其他線程出現故障,那么在我看來使用Thread.stop
是完全安全的。
您應該只使用ExecutorService並向其提交任務,而不是使用隊列和線程。
如果要停止,可以使用shutdown()
方法。
您可以使用stop(),前提是您了解它被棄用的原因。 它工作得很好,但可能有副作用。 即你已經知道你在做什么來使用它。
BTW:這不會中斷JNI呼叫。 如果你需要它,你必須啟動一個單獨的進程,你kill -9
,以確保它會死。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.