如何杀死java线程?
我在谷歌上找到了杀死java线程的解决方案。存在两种解决方案:如何杀死java线程?,java,multithreading,Java,Multithreading,我在谷歌上找到了杀死java线程的解决方案。存在两种解决方案: 立旗 使用Thread.interrupt 但这两种都不适合我。在我的线程中,我调用了一个需要很长时间才能完成的第三方api。我想让用户取消这个线程,如果它需要太多的时间 那我怎么才能杀死这根线呢?提前谢谢。你可以试试,但是。最理想的情况是,如果需要,您正在调用的API应该有一种中断操作的方法(如果API本身没有提供一种更干净的中断其进程的方法,您尝试过吗?)。Thread.interrupt()是唯一普遍适用的安全方法。当然,您可
那我怎么才能杀死这根线呢?提前谢谢。你可以试试,但是。最理想的情况是,如果需要,您正在调用的API应该有一种中断操作的方法(如果API本身没有提供一种更干净的中断其进程的方法,您尝试过吗?)。
Thread.interrupt()
是唯一普遍适用的安全方法。当然,您可以使用其他应用程序级别的信号(例如对易失性变量的条件检查)来自行终止。其他方法(如所有不推荐使用的Thread.xx方法)可能会以不确定的方式污染应用程序的状态,并且需要重新加载所有应用程序状态。您可以在Thread对象上调用stop
方法,但强烈建议不要这样做。请阅读以下内容:
您是否有对API进行微小更改的自由?这个阻塞调用是CPU绑定的还是IO绑定的?如果它是IO绑定的,并且您有权访问底层套接字/远程通信对象,那么关闭该对象可以带来奇迹。至少比停止线程要好。理论上,您可以调用已弃用的
thread.stop()
方法。但请注意,这可能会导致应用程序以意外和不可预测的方式运行。。。这取决于第三方库实际在做什么Thread.stop()
和朋友基本上是不安全的
最好的解决方案是修改第三方库以响应Thread.interrupt。如果你做不到,那就抛弃它,找到/使用更好的库。生成一个单独的进程,并使用操作系统设施杀死它。您必须调用“C”来执行此操作,但代码不多。您没有说出正在运行的操作系统。在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
,如果不是,则退出
这样做的好处是,完成后您仍然可以进行清理。run方法完成后,线程将自动终止。我将把调用放在一个需要很长时间的第三方api中,可调用
,然后使用指定超时的SingleThreadExecutor
执行它
按照这种方法,如果调用第三方API的时间超过了超时时间,线程将被终止,下面是一些代码来举例说明我所说的:
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
}
};
ExecutorService executor=Executors.newSingleThreadExecutor();
试一试{
//===========================这里==================
未来作业=执行者提交(第三方可调用);
执行器等待终止(超时,时间单位秒);
如果(!job.isDone())
debug(“对第三方API的长时间调用未完成”);
//=========================================
}捕获(异常exc){
exc.printStackTrace();
}最后{
如果(!executor.isShutdown())
执行者。关机现在();
}
}
私有静态可调用thirdParytCallable=新可调用(){
公共布尔调用()引发异常{
//对第三方长API的调用
//.......
对于(long i=0;iwell,这应该行得通,但对我来说太重了,它会增加集成和共享数据的复杂性。你不需要杀死它,就让它们自杀吧……Thread.interrupt只是故事的一半,你正在中断的线程必须支持使用中断标志的中断策略……调用的就是那个标志Thread.interrupt将重置。大多数情况下,Thread.interrupt不会终止线程,而是线程继续运行。在这种情况下,什么是最佳解决方案。@Kathir:Thread.interrupt在被阻止时向线程发送InterruptedException。您的工作是捕获并适当关闭它。@YannRamin,您如何关闭i正确关闭?是的,Ramin,请详细说明?Joshua Bloch的“有效Java”第二版第68项:更喜欢执行器和任务而不是线程未来+调用该方法不允许强制停止线程。Future.cancel
方法使用thread.interrupt()
,我们已经被告知thread.interrupt()
不是一个解决方案。