如何在Java中杀死Java .lang. thread ?
当前回答
在用Java开发了15年之后,有一件事我想对世界说。
弃用Thread.stop()和所有反对其使用的神圣之战只是另一个坏习惯或设计缺陷不幸成为现实…(如。想谈谈Serializable接口吗?)
争论的焦点在于,杀死线程会使对象处于不一致的状态。所以呢?欢迎来到多线程编程。你是一个程序员,你需要知道你在做什么,是的。杀死线程会使对象处于不一致状态。如果你担心它使用一个标志,让线程优雅地退出;但有很多时候,我们没有理由担心。
但没有. .如果你输入thread.stop(),你很可能会被所有查看/注释/使用你代码的人杀死。所以你必须使用一个标志,调用interrupt(),在你的代码周围放置if(!标志),因为你根本没有循环,最后祈祷你用来进行外部调用的第三方库是正确编写的,并且没有不正确地处理InterruptException。
其他回答
试图突然终止线程是众所周知的糟糕编程实践,也是糟糕应用程序设计的证据。多线程应用程序中的所有线程显式或隐式地共享相同的进程状态,并被迫相互协作以保持一致,否则您的应用程序将容易出现很难诊断的错误。因此,开发人员有责任通过仔细和清晰的应用程序设计来保证这种一致性。
对于受控线程终止,有两种主要的正确解决方案:
使用共享volatile标志 使用Thread.interrupt()和Thread.interrupted()方法。
关于突发线程终止相关问题的详细解释,以及受控线程终止的错误和正确解决方案的示例,可以在这里找到:
https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads
请参阅Sun的这篇文章,了解他们为什么弃用thread .stop()。它将详细说明为什么这是一个糟糕的方法,以及应该做些什么来安全地停止线程。
他们推荐的方法是使用一个共享变量作为标志,要求后台线程停止。这个变量可以由请求线程终止的另一个对象设置。
一般来说你不会…
你可以使用Thread.interrupt() (javadoc link)命令它中断正在做的事情。
在javadoc中有一个很好的解释(java technote链接)
一种方法是设置一个类变量并将其用作哨兵。
Class Outer {
public static volatile flag = true;
Outer() {
new Test().start();
}
class Test extends Thread {
public void run() {
while (Outer.flag) {
//do stuff here
}
}
}
}
设置一个外部类变量,如上面例子中的flag = true。将其设置为false以“杀死”线程。
There is of course the case where you are running some kind of not-completely-trusted code. (I personally have this by allowing uploaded scripts to execute in my Java environment. Yes, there are security alarm bell ringing everywhere, but it's part of the application.) In this unfortunate instance you first of all are merely being hopeful by asking script writers to respect some kind of boolean run/don't-run signal. Your only decent fail safe is to call the stop method on the thread if, say, it runs longer than some timeout.
但是,这只是“体面的”,而不是绝对的,因为代码可以捕获ThreadDeath错误(或您显式抛出的任何异常),而不是像一个绅士线程应该做的那样重新抛出它。所以,AFAIA的底线是没有绝对的故障保险。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 自动化invokerrequired代码模式
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder