繁体   English   中英

如何杀死java线程?

[英]How to kill a java thread?

我谷歌杀死java线程的解决方案。 并且存在两种解决方案:

  1. 设置一面旗帜
  2. 使用Thread.interrupt

但他们两个都不适合我。 在我的帖子中,我称第三方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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM