[英]How to kill a java thread?
我谷歌杀死java线程的解决方案。 并且存在两种解决方案:
但他们两个都不适合我。 在我的帖子中,我称第三方api需要很长时间才能完成。 如果需要花费太多时间,我想让用户取消这个帖子。
那我怎么能杀掉这个帖子呢? 提前致谢。
Thread.interrupt()
是唯一通常适用的安全方法。 您当然可以使用其他应用程序级信号(例如对volatile变量进行条件检查)来自行终止。 其他方法(例如所有已弃用的Thread.xx方法)可能会以非确定性方式污染应用程序的状态,并且需要重新加载所有应用程序状态。
理论上,您可以调用已弃用的Thread.stop()
方法。 但请注意,这可能会导致您的应用程序以意外和不可预测的方式运行......取决于第三方库实际执行的操作。 Thread.stop()
和朋友从根本上说是不安全的。
最好的解决方案是修改第三方库以响应Thread.interrupt。 如果你做不到,那就放弃它,找到/使用一个更好的库。
我将调用第三方api,这需要很长时间才能进入Callable<DataTypeReturnedBy3rdPartAPI>
,然后使用指定超时的SingleThreadExecutor
执行它。
按照这一办法,该线程将如果调用第三方API需要长于被杀死 timeOut
,这里是一些代码来举例说明我说的话:
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
//================= HERE ==================
Future<Boolean> job = executor.submit(thirdPartyCallable);
executor.awaitTermination(timeOut, TimeUnit.SECONDS);
if(!job.isDone())
logger.debug("Long call to 3rd party API didn't finish");
//=========================================
} catch (Exception exc) {
exc.printStackTrace();
} finally {
if(!executor.isShutdown() )
executor.shutdownNow();
}
}
private static Callable<Boolean> thirdParytCallable = new Callable<Boolean>() {
public Boolean call() throws Exception {
//Call to long 3rd party API
//.......
for(long i = 0;i<99999991999999L;i++) {
Thread.sleep(10L);// Emulates long call to 3rd party API
System.out.print(".");
}
return Boolean.valueOf(true);//Data from 3rd party API
}
};
生成一个单独的进程并使用操作系统设施将其终止。 您将不得不调用“C”来执行此操作,但代码不会太多。 你没有说你在运行什么操作系统。
您可以尝试Thread.stop() ,但风险自负 。 最理想的情况是,您正在调用的API应该有一种方法可以在需要时中断操作(如果API本身没有提供更简洁的方法来中断其进度,那么这就是Thread.interrupt() ,你试过吗?) 。
您可以在Thread对象上调用stop
方法,但强烈建议您不要这样做。 阅读本文: http : //download.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
您是否可以自由地对API进行细微更改? 这个阻塞调用是CPU绑定还是IO绑定? 如果它是IO绑定的,并且您可以访问底层套接字/远程通信对象,则关闭该对象可以创建奇迹。 它至少比停止线程更好。
在java.util.concurrent.FutureTask中 ,超时取消的机制被视为抛出java.util.concurrent.TimeoutException 。
您可以检查这一点,好像有一些东西会被超时自动中断。
由于(正确地)不推荐使用Thread.stop()
,通常可以通过将标志设置为true来实现。 像这样的东西:
通话类:
...
workListExecutor.stop()
...
WorkListExecutor.class:
boolean running = true;
void stop(){
running = false;
}
void run(){
while (running) {
... do my stuff ...
}
}
这假设你的线程有某种主循环(通常是这种情况)。 如果你的循环中的代码太大,你可以定期检查running
是否仍然是true
,如果不是,则进行拯救。
这样做的好处是,您可以在完成后进行清理。 运行方法完成后,线程将自动终止。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.