简体   繁体   English

如何杀死java线程?

[英]How to kill a java thread?

I google the solution for killing a java thread. 我谷歌杀死java线程的解决方案。 And there exists two solutions: 并且存在两种解决方案:

  1. set a flag 设置一面旗帜
  2. using Thread.interrupt 使用Thread.interrupt

But both of them are not suitable for me. 但他们两个都不适合我。 In my thread, I call a third-party api which takes a long time to complete. 在我的帖子中,我称第三方api需要很长时间才能完成。 and I want to let the user to cancel this thread if it takes too much time. 如果需要花费太多时间,我想让用户取消这个帖子。

So how can I kill this thread ? 那我怎么能杀掉这个帖子呢? Thanks in advance. 提前致谢。

Thread.interrupt() is the only safe method which is generally applicable. Thread.interrupt()是唯一通常适用的安全方法。 You can of course use other application-level signals (such as a conditional check on a volatile variable) to self-terminate. 您当然可以使用其他应用程序级信号(例如对volatile变量进行条件检查)来自行终止。 Other methods (such as all the deprecated Thread.xx methods) can pollute your application's state in non-deterministic ways, and would require reloading all application state. 其他方法(例如所有已弃用的Thread.xx方法)可能会以非确定性方式污染应用程序的状态,并且需要重新加载所有应用程序状态。

In theory, you could call the deprecated Thread.stop() method. 理论上,您可以调用已弃用的Thread.stop()方法。 But beware that this could result in your application behaving in unexpected and unpredictable ways ... depending on what the third party library is actually doing. 但请注意,这可能会导致您的应用程序以意外和不可预测的方式运行......取决于第三方库实际执行的操作。 Thread.stop() and friends are fundamentally unsafe. Thread.stop()和朋友从根本上说是不安全的。

The best solution is to modify the 3rd-party library to respond to Thread.interrupt. 最好的解决方案是修改第三方库以响应Thread.interrupt。 If you cannot, then ditch it and find / use a better library. 如果你做不到,那就放弃它,找到/使用一个更好的库。

I would put the call a third-party api which takes a long time into a Callable<DataTypeReturnedBy3rdPartAPI> and then execute it with a SingleThreadExecutor specifying a timeout . 我将调用第三方api,这需要很长时间才能进入Callable<DataTypeReturnedBy3rdPartAPI> ,然后使用指定超时SingleThreadExecutor执行它。

Following this approach, the thread will be killed if the call to third party API takes longer than timeOut , here is some code to exemplify what I am saying: 按照这一办法,该线程将如果调用第三方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
  }
}; 

Spawn a separate process and kill it using OS facilities. 生成一个单独的进程并使用操作系统设施将其终止。 You'll have to call into "C" to do it but it won't be much code. 您将不得不调用“C”来执行此操作,但代码不会太多。 You didn't say what OS you are running on. 你没有说你在运行什么操作系统。

You can try Thread.stop() , but at your own risk . 您可以尝试Thread.stop() ,但风险自负 Optimally, the API you're calling should have a way to interrupt the operation if needed (which is what Thread.interrupt() is for if the API itself does not provide a cleaner way to interrupt its progress, have you tried it?). 最理想的情况是,您正在调用的API应该有一种方法可以在需要时中断操作(如果API本身没有提供更简洁的方法来中断其进度,那么这就是Thread.interrupt() ,你试过吗?) 。

You can invoke the stop method on the Thread object but it is strongly recommended that you don't. 您可以在Thread对象上调用stop方法,但强烈建议您不要这样做。 Read this: http://download.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html 阅读本文: http//download.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html

Do you have the freedom to make minor changes to the API? 您是否可以自由地对API进行细微更改? Is this blocking call CPU bound or IO bound? 这个阻塞调用是CPU绑定还是IO绑定? If it is IO bound and if you have access to the underlying socket/remote communication object, closing that object can do wonders. 如果它是IO绑定的,并且您可以访问底层套接字/远程通信对象,则关闭该对象可以创建奇迹。 It is at least better than stopping the thread. 它至少比停止线程更好。

In java.util.concurrent.FutureTask , the mechanism of cancellation by timeout is acted as throwing java.util.concurrent.TimeoutException . java.util.concurrent.FutureTask中 ,超时取消的机制被视为抛出java.util.concurrent.TimeoutException

You may check out this as if there are something to be interrupted automatically by timeout. 您可以检查这一点,好像有一些东西会被超时自动中断。

Since Thread.stop() is (rightly) deprecated, generally this is accomplished by setting a flag to true. 由于(正确地)不推荐使用Thread.stop() ,通常可以通过将标志设置为true来实现。 Something like this: 像这样的东西:

Calling Class: 通话类:

...
workListExecutor.stop()
...

WorkListExecutor.class: WorkListExecutor.class:

boolean running = true;

void stop(){
  running = false;
}

void run(){
  while (running) {
    ... do my stuff ...
  }
}

This is assuming your thread has some kind of main loop (usually the case). 这假设你的线程有某种主循环(通常是这种情况)。 If the code in your loop is too big, you can periodically check if running is still true , and bail out if it's not. 如果你的循环中的代码太大,你可以定期检查running是否仍然是true ,如果不是,则进行拯救。

This has the advantage that you can still clean up when you're done. 这样做的好处是,您可以在完成后进行清理。 The thread will be killed automatically when your run method finishes. 运行方法完成后,线程将自动终止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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