有没有办法让线程告诉哪个线程中断了它?

时间:2014-08-02 01:16:16

标签: java multithreading interrupt

线程有没有办法告诉哪个线程中断了它?

例如:

...
if (isInterrupted())  {
    // look-up the thread that interrupted this
        // act accordingly
}

Thread没有显示任何内容。

// ========================

编辑:

这不是我正在寻找的消息或事件机制。

但是,这看起来非常原始。 获取类类型,线程组或者可能只是中断的优先级的方法 线程会携带一些信息来处理。

典型的用途是关闭系统 - 打断它们以使它们脱离它们 阻止方法,我现在还没有想到的另一种方法。

4 个答案:

答案 0 :(得分:4)

  

线程有没有办法告诉哪个线程中断了它?

总之:不。

标准Java SE类库中没有支持此功能的功能。

事实上,即使问题也没有明确定义:

  • 如果一个线程被不同的线程多次中断会怎么样?应该报告哪一个?

  • 线程检测到它已经被中断(例如通过isInterrupted调用)并找出它做了什么线程之间的竞争条件怎么样?

正如Sotirios评论的那样:如果发出信号的线程需要找出哪个线程发出信号,那么interrupt可能是错误的机制。您可能需要构建自己的事件机制,其中事件随身携带所需的信息。

答案 1 :(得分:2)

在中断线程之前,将所需信息存储在被中断线程可以获取的位置。然后,当线程被中断时,让它在存储它的任何地方检查该信息。

答案 2 :(得分:1)

您无法在标准线程中告知并且如果您需要这样做,那么队列更有可能是有用的。

在这种情况下,更好的解决方案可能是状态变化。

e.g。

// change state in a thread safe manner
sharedObject.setState(Mode.ACTION);
thread.interrupt();


// doesn't need to know about other threads, just state changes.
if (isInterrupted())  {
    switch(sharedObject.getState()) {
        case ACTION:

    }
}

更一般地说,您可以为要运行的线程注入任务。

 // calling thread needs an action to perform.
 sharedThread.execute(runnable); // or invokeLater()

 // polling thread, use take() if you want to block.
 for(Runnable run; (run = runQueue.poll()) != null;)
      run.run();

然而,这并不意味着它只是因为它可能不是一个好主意而无法完成。

public class Main {

    static class MyThread extends Thread {
        protected final Queue<Thread> interruptingThreads = new ConcurrentLinkedQueue<>();

        MyThread(Runnable target) {
            super(target);
        }

        public Queue<Thread> getInterruptingThreads() {
            return interruptingThreads;
        }

        @Override
        public void interrupt() {
            interruptingThreads.add(Thread.currentThread());
            super.interrupt();
        }
    }

    public static void main(String... ignored) throws Exception {
        Thread t = new MyThread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.err.println("Interrupted by :" + ((MyThread) Thread.currentThread()).getInterruptingThreads());
                }
            }
        });
        t.start();
        Thread.sleep(500);
        t.interrupt();
    }
}

打印

java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at Main$1.run(Main.java:53)
    at java.lang.Thread.run(Thread.java:745)
Interrupted by :[Thread[main,5,]]

如果这是调试目的,您还可以添加中断线程的堆栈跟踪,称为interrupt()

答案 3 :(得分:0)

如果您只是需要知道用于调试的中断线程,而不是实际在代码中,我发现以下帖子很有用,其中介绍了添加新的SecurityManager:Is there any way in Java to log *every* Thread interrupt?