我想检查某个线程是否从其他某个线程中断,而无需轮询来检查-即某种监视器。
具体来说,我要执行的操作是在线程中断时强制杀死(停止)线程。我将在下面提供一个代码示例,作为到目前为止到目前为止所做工作的一个简单示例-它可以工作,但是轮询以检查Thread是否被中断是次优的,我想避免这种情况。
public class ThreadTest
{
public static void main(final String[] args) throws InterruptedException
{
final Thread outerThread = new Thread()
{
@Override
public void run()
{
// Need to externally monitor the thread to detect and process interrupts (for cancellation)
final Thread thread = Thread.currentThread();
new Thread()
{
@Override
public void run()
{
while (true)
{
try
{
Thread.sleep(500);
}
catch (final InterruptedException e)
{}
if (thread.isInterrupted())
{
// Then kill it
thread.stop();
return;
}
}
}
}.start();
uninterruptibleForever();
}
};
outerThread.start();
// Ensure the thread has time to start up
Thread.sleep(500);
outerThread.interrupt();
// The thread should terminate at this point and not continue.
}
/** Some arbitrary task that runs forever and ignores interrupts */
public static void uninterruptibleForever()
{
while (true)
{
System.out.println(MessageFormat.format("I''m still running at {0}", new Date().toLocaleString()));
}
}
}
答案 0 :(得分:2)
对于您不使用Thread#stop()
的建议,我的建议不够强烈。
它永远不应该存在,已经过时了,坦率地说应该在20年前删除。
您不知道线程在停止时正在做什么,并且很容易破坏共享对象并使外部资源(例如文件)处于无效状态。
假设线程正在调整共享ArrayList<>
的大小,则存在对象损坏的风险,并且整个程序会以无法修复的方式间歇性地失败。
请勿使用Thread#stop()
,因为它已损坏且无法修复。
这是Java的一个可怕功能,它使人们陷入有关线程的无效技术。
深入讨论-仅在子类中覆盖interrupt()
怎么样?
public void interrupt(){
this.stop();
}
您已决定将Thread
(而不是Runnable
)作为子类,这样可以“起作用”。在您所做的事情上“工作”。根本没有用。
解决此问题的唯一有效方法是让您要终止的线程通过响应interrupt()
作为到达适当点然后干净终止的指令来进行协作。
或者,您可以创建另一个标志来指示线程应结束。
答案 1 :(得分:0)
我不知道您为什么需要从外部监视线程。但是,这里有一个小样本,如果您确实需要它,您可以如何做:
import java.util.LinkedList;
import java.util.List;
public abstract class MonitoredCallable implements Runnable {
private final List<InterruptedHandler> interruptedHandlers = new LinkedList<>();
protected abstract void runInternal() throws Exception;
@Override
public final void run() {
try {
runInternal();
} catch(Exception ex) {
}
for (InterruptedHandler interruptedHandler : interruptedHandlers) {
interruptedHandler.threadInterrupted(this);
}
}
public void addInterruptedHandler(InterruptedHandler interruptedHandler) {
this.interruptedHandlers.add(interruptedHandler);
}
public static interface InterruptedHandler {
void threadInterrupted(Thread t);
}
}
现在像这样使用它:
MonitoredThread mt = new MonitoredThread() {
@Override
protected void runInternal() throws Exception {
//dosomething
}
};
mt.addInterruptedHandler(t->t.stop());