有没有一种方法让一个线程知道是哪个线程打断了它?

6

线程有办法知道哪个线程打断了它吗?

例如:

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

线程 没有显示任何内容。

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

编辑:

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

但是,这似乎非常原始。 获取中断线程的类类型、线程组或优先级的方法将携带一些信息以便处理。

典型用途是系统关闭-- 中断它们以使它们退出阻塞方法,并且现在我想不到其他用途了。


3
我觉得中断不是合适的通知机制。你能描述一下你的使用情况吗? - Sotirios Delimanolis
4个回答

4
有没有一种方法让一个线程知道哪个线程打断了它?
简而言之:没有。
Java SE标准类库中没有支持此操作的功能。
实际上,这个问题本身并没有被很好地定义:
- 如果一个线程被多个不同的线程打断,会发生什么?应该报告哪一个? - 如果一个线程检测到它已经被打断(例如通过isInterrupted调用),并找出是哪个线程打断的之间存在竞争条件,那怎么办?
正如Sotirios所评论的:如果被通知的线程需要找出是哪个线程通知了它,那么interrupt可能是错误的机制。您可能需要构建自己的事件机制,在其中事件携带您需要的信息。

是的,事件机制听起来更好。 - Sotirios Delimanolis

2

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


1
假设在多线程(超过2个)环境下,如何确保被中断的线程能够看到中断它的线程的信息? - Sotirios Delimanolis
在中断线程之前,你完成了存储信息的工作,并使用适当的同步机制保护了保存信息的容器。 - David Schwartz

1

你无法在标准线程中判断,如上所述,如果需要这样做,则队列更有用。

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

例如:

// 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() 的位置。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接