检查另一个线程是否被中断,而不进行轮询

时间:2018-07-25 13:35:37

标签: java multithreading

我想检查某个线程是否从其他某个线程中断,而无需轮询来检查-即某种监视器。

具体来说,我要执行的操作是在线程中断时强制杀死(停止)线程。我将在下面提供一个代码示例,作为到目前为止到目前为止所做工作的一个简单示例-它可以工作,但是轮询以检查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()));
        }
    }
}

2 个答案:

答案 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());