如何杀死Java中的线程?

如何杀死Java中的线程?

由Sun看到这个线程为什么不推荐使用Thread.stop() 。 它详细说明了为什么这是一个不好的方法,应该做些什么来安全地停止一般的线程。

他们推荐的方式是使用共享variables作为标志,要求后台线程停止。 这个variables可以由另一个请求线程终止的对象来设置。

一般你不..

你要求它用Thread.interrupt()(javadoc链接)来打断它正在做的事情。

为什么在这里的javadoc (java技术链接)的一个很好的解释

在Java中,线程不会被终止,但是线程的停止是以合作的方式完成的 。 线程被要求终止,线程可以正常closures。

通常会使用一个volatile boolean字段,当线程设置为相应的值时,该字段会定期检查并终止。

不会使用boolean来检查线程是否应该终止 。 如果你使用volatile作为一个字段修饰符,这将工作可靠,但是如果你的代码变得更加复杂,为了在while循环内部使用其他的阻塞方法,可能会发生,你的代码将不会终止 ,或者至less需要更长的时间如你所愿。

某些阻塞库方法支持中断。

每个线程已经有一个布尔标志中断状态 ,你应该利用它。 它可以这样实现:

 public void run() { try { while(!Thread.currentThread().isInterrupted()) { // ... } } catch (InterruptedException consumed) /* Allow thread to exit */ } } public void cancel() { interrupt(); } 

源于Java实践中的并发性的源代码。 由于cancel()方法是公共的,你可以让另一个线程调用这个方法。

还有一个命名不清的静态方法interrupted ,清除当前线程的中断状态。

一种方法是设置一个类variables并将其用作定点。

 Class Outer { public static volatile flag = true; Outer() { new Test().start(); } class Test extends Thread { public void run() { while (Outer.flag) { //do stuff here } } } } 

在上面的例子中设置一个外部类variables,即flag = true。 将其设置为false以“杀死”线程。

有一种方法可以做到这一点。 但是,如果你不得不使用它,不pipe你是一个糟糕的程序员,还是使用了糟糕的程序员编写的代码。 所以,你应该考虑停止成为一个糟糕的程序员或停止使用这个错误的代码。 这种解决scheme只适用于没有其他方式的情况。

 Thread f = <A thread to be stopped> Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} ); m.setAccessible( true ); m.invoke( f , new ThreadDeath() ); 

我想根据已经积累的意见添加几个意见。

  1. 如果安全pipe理器允许,Thread.stop()将停止一个线程。
  2. Thread.stop()是危险的。 话虽如此,如果您正在JEE环境中工作,并且您无法控制所调用的代码,则可能有必要。
  3. 你不应该停止停止一个容器工作线程。 如果你想运行易于挂起的代码,(仔细地)启动一个新的守护进程线程并监视它,如果有必要的话会被终止。
  4. stop()会在调用线程上创build一个新的ThreadDeath错误,然后导致将该错误应用于目标线程。 因此,堆栈跟踪一般是毫无价值的。
  5. 在JRE 6中,stop()与安全pipe理器一起检查,然后调用stop1()来调用stop0()。 stop0()是本地代码。

这个问题相当模糊。 如果你的意思是“如何编写一个程序,以便一个线程在我想要的时候停止运行”,那么其他各种响应应该是有帮助的。 但是,如果你的意思是“我有一个服务器的紧急情况,我现在不能重新启动,我只需要一个特定的线程死亡,什么可能”,那么你需要一个干预工具来匹配监视工具,如jstack

为此我创build了jkillthread 。 请参阅其使用说明。

我会投票Thread.stop()

例如,你有一个持久的操作(如networking请求)。 假设您正在等待响应,但是可能需要一些时间并且用户导航到其他用户界面。 这个等待的线程现在是a)没用的b)潜在的问题,因为当他将得到结果时,它是完全无用的,他将触发callback,可能导致一些错误。

所有这一切,他可以做CPU的激烈响应处理。 而且,作为开发者,你甚至不能停止它,因为你不能在所有的代码中抛出if (Thread.currentThread().isInterrupted())行。

所以无法强制停止一个线程奇怪。

当然,你正在运行某种不完全可信的代码。 (我个人是这样的,允许上传的脚本在我的Java环境中执行,是的,每个地方都有安全警报响起,但是它是应用程序的一部分。)在这个不幸的例子中,首先你只需要问脚本编写者尊重某种布尔运行/不运行信号。 你唯一可行的失败保险就是调用线程上的停止方法,比如说,如果运行时间超过某个超时时间。

但是,这只是“体面的”,而不是绝对的,因为代码可以捕获ThreadDeath错误(或者你明确抛出的任何exception),而不是像绅士的线程那样重新抛出它。 所以,底线是AFAIA没有绝对的失败保险。

没有办法优雅地杀死一个线程。

你可以尝试中断线程,一个常见的策略是使用毒丸来通知线程停止自己

 public class CancelSupport { public static class CommandExecutor implements Runnable { private BlockingQueue<String> queue; public static final String POISON_PILL = “stopnow”; public CommandExecutor(BlockingQueue<String> queue) { this.queue=queue; } @Override public void run() { boolean stop=false; while(!stop) { try { String command=queue.take(); if(POISON_PILL.equals(command)) { stop=true; } else { // do command System.out.println(command); } } catch (InterruptedException e) { stop=true; } } System.out.println(“Stopping execution”); } } 

}

 BlockingQueue<String> queue=new LinkedBlockingQueue<String>(); Thread t=new Thread(new CommandExecutor(queue)); queue.put(“hello”); queue.put(“world”); t.start(); Thread.sleep(1000); queue.put(“stopnow”); 

http://anandsekar.github.io/cancel-support-for-threads/

尝试突然线程终止是众所周知的糟糕的编程实践和糟糕的应用程序devise的证据。 multithreading应用程序中的所有线程明确和隐含地共享相同的进程状态,并被迫相互协作以保持一致,否则您的应用程序将容易出现将很难诊断的错误。 所以,开发人员有责任通过仔细和清晰的应用程序devise来保证这种一致性。

受控线程terminal有两个主要的正确解决scheme:

  • 使用共享易失性标志
  • 使用一对Thread.interrupt()和Thread.interrupted()方法。

有关突发线程终止的问题的良好和详细的解释以及受控线程终止的错误和正确的解决scheme的例子可以在这里find:

https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads

这里有一些关于这个问题的好消息:

你用InterruptedException做什么?

干净地closures线程

我没有得到在Android的中断工作,所以我用这个方法,完美的作品:

 boolean shouldCheckUpdates = true; private void startupCheckForUpdatesEveryFewSeconds() { Thread t = new Thread(new CheckUpdates()); t.start(); } private class CheckUpdates implements Runnable{ public void run() { while (shouldCheckUpdates){ //Thread sleep 3 seconds System.out.println("Do your thing here"); } } } public void stop(){ shouldCheckUpdates = false; }