- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个多线程 java 项目,我想添加一个方法 stop() 来停止所有正在运行的线程。问题是这个项目是别人开发的,我不熟悉它是如何实现多线程的。
我所知道的是,一旦项目启动,就会调用许多线程并永远运行。有没有办法找到所有正在运行的线程并停止它们?我搜索了很多,找到了如何获取正在运行的线程列表:
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
下一步要做什么来停止所有正在运行的线程?
我想停止这些线程的原因是我需要将这个项目作为一个包部署到 OSGi 容器中。一旦 bundle 启动,多个线程将永远运行。所以我需要实现一个 destroy() 方法来停止所有线程来控制 bundle 生命周期。
怎么样
for (Thread t : Thread.getAllStackTraces().keySet())
{ if (t.getState()==Thread.State.RUNNABLE)
t.interrupt();
}
for (Thread t : Thread.getAllStackTraces().keySet())
{ if (t.getState()==Thread.State.RUNNABLE)
t.stop();
}
最佳答案
这是一个危险的想法。 Thread.stop()
的 Javadoc解释:
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait.
从根本上说,线程需要构建和设计为安全终止,安全地杀死任意线程是不可能的。一个相当标准的模式是这样实现的:
public abstract class StoppableRunnable implements Runnable {
private volatile boolean stopWork;
private boolean done;
public final void run() {
setup();
while(!stopWork && !done) {
doUnitOfWork();
}
cleanup();
}
/**
* Safely instructs this thread to stop working,
* letting it finish it's current unit of work,
* then doing any necessary cleanup and terminating
* the thread. Notice that this does not guarentee
* the thread will stop, as doUnitOfWork() could
* block if not properly implemented.
*/
public void stop() {
stopWork = true;
}
protected void done() {
done = true;
}
protected void setup() { }
protected void cleanup() { }
/**
* Does as small a unit of work as can be defined
* for this thread. Once there is no more work to
* be done, done() should be called.
*/
protected abstract void doUnitOfWork();
}
您暗示您不是这些线程的作者,这表明它们可能无法安全停止。在这种情况下,您可以调用 Thread.interrupt()
指示线程停止它正在做的事情(而不是上面描述的模式,你可以使用 Thread.interrupt()
来达到类似的效果)但是类似地,如果线程的设计者没有编写它来处理中断,这可能不会做任何事情或导致不一致的状态或其他错误。
最终,Thread.stop()
是您想要的,如果您只想“[强制] 线程停止执行”并且不能修改线程的实现;然而,就像在 Unix 中使用 kill
一样,这是一个危险的提议,您应该在以这种方式终止线程后,本质上认为您的 JVM 处于不稳定且无法修复的状态,并尝试退出程序之后尽快。
关于您中断然后停止的建议:
这里仍然存在很多问题,特别是,中断并不能保证线程会立即中断(它的工作方式与上面的 StoppableRunnable
类似,但不太明确),而是设置一个标志线程应尽可能中断。这意味着您可以调用 Thread.interrupt()
,线程可以启动它的正确中断处理行为,然后在中途调用 Thread.stop()
触发,猛烈地杀死线程并可能破坏你的 JVM。调用 Thread.interrupt()
不保证线程何时或如何响应该中断,这就是为什么我更喜欢 StoppableRunnable
中的显式行为。不用说,如果您打算调用 Thread.stop()
,那么先调用 Thread.interrupt()
将无济于事。我不推荐这样做,但您也可以首先调用 Thread.stop()
。
此外,要认识到运行循环的代码本身在一个线程中 - 这意味着您的循环很可能首先终止自身,让所有其他线程继续运行。
关于java - 如何找到并停止所有当前正在运行的线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15624296/
我有一个加号/减号按钮,希望用户不能选择超过 20 个但不知道如何让它工作。我尝试使用 min="1"max="5 属性,但它们不起作用。这是我的代码和一个 fiddle 链接。https://jsf
我正在尝试复制顶部底部图,如示例 here但它没有正确渲染(紫色系列有 +ve 和 -ve 值,绿色为负值)留下杂乱的人工制品。我也在努力创建一个玩具示例来复制这个问题,所以我希望尽管我缺乏数据,但有
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 已关闭 6 年前。 社区去年审查了是
这个问题在这里已经有了答案: Adding two positive integers gives negative answer.Why? (4 个答案) 关闭 5 年前。 我遇到了一个奇怪的问题
有谁知道如何将字符串值类型 -4,5 或 5,4 转换为 double -4.5 或 5.4? 最佳答案 只需使用 Double.parseDouble(Locale, String); 糟糕,我很困
我正在尝试根据 TextBlob 分类插入一个仅包含“正”或“负”字符串的新数据框列:对于我的 df 的第一行,结果是 ( pos , 0.75, 0.2499999999999997)我想要' 正
我对 VBA 非常陌生,无法理解如何在一个循环中完成 2 个任务。我非常感谢您的帮助。 我已经能够根据第 3 列中的数据更改第 2 列中的数值,但我不明白如何将负值的字体更改为红色。 表格的大小每月都
欢迎, 我正在使用 jquery 通过 POST 发送表单。 这就是我获得值(value)的方式。 var mytext = $("#textareaid").val(); var dataStrin
double d = 0; // random decimal value with it's integral part within the range of Int32 and always p
我有这个字符串: var a='abc123#xyz123'; 我想构建 2 个正则表达式替换函数: 1) 用 '*' 替换所有确实有 future '#'的字符(不包括'#') 所以结果应该是这样的
我正在使用 DialogFragment。当用户从 Gmail 平板电脑应用程序的屏幕与下面示例图片中的编辑文本进行交互时,我希望正面和负面按钮保持在键盘上方。 在我的尝试中不起作用,这是我的 Dia
从组装艺术一书中,我复制了这句话: In the two’s complement system, the H.O. bit of a number is a sign bit. If the H.O
是否有更好更优雅的方法来实现下面的简单代码(diffYear、A 和 B 是数字): diffYear = yearA - yearB; if (diffYear == 0) { A = B
我正在设计一种语言,并尝试确定 true 应该是 0x01 还是 0xFF。显然,所有非零值都将转换为 true,但我正在尝试确定确切的内部表示。 每种选择的优点和缺点是什么? 最佳答案 没关系,只要
在我的 dialogfragment 类的 OnCreateDialog 中,我正在这样做: AlertDialog.Builder builder = new AlertDialog.Builder
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda usin
我偶然发现了一个奇怪的 NSDecimalNumber 行为:对于某些值,调用 integerValue、longValue、longLongValue 等,返回意想不到的值(value)。示例: l
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda using
我有这个正则表达式来测试用户输入是否有效: value.length === 0 || value === '-' || (!isNaN(parseFloat(value)) && /^-?\d+\.
我想用高斯混合模型拟合数据集,数据集包含大约 120k 个样本,每个样本有大约 130 个维度。当我使用 matlab 执行此操作时,我运行脚本(簇号为 1000): gm = fitgmdist(d
我是一名优秀的程序员,十分优秀!