如何在中断线程 B 时识别线程 A 的名称或任何上下文信息?

How to identify name or any contextual info of thread A when it interrupts thread B?

我在类似的行中发现了一个问题:

  1. 如何在中断线程 B 时识别线程 A 的名称或任何上下文信息?
  2. 即使我们获得了线程 A 的名称,也有可能存在多个同名线程,如下所述:https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#interrupt-- Every thread has a name for identification purposes. More than one thread may have the same name. If a name is not specified when a thread is created, a new name is generated for it.
  3. 这是否意味着我必须创建继承“java.lang.Thread”的自定义线程?

代码示例

Thread threadA = new Thread(new Runnable() {
public void run() {
    try {
      Thread.sleep(500);
    } catch (InterruptedException ex) { }
    System.out.println("I am going to interrupt, catch me if you can");
    threadB.interrupt();
  }
});

Thread threadB = new Thread(new Runnable() {
public void run() {
    try {
            System.out.println("threadB going to be interrupted");
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            //How to find name or any contextual info of threadA here?
            Thread.currentThread().interrupt();
        }
    
  }
});

threadB.start();
threadA.start();

如果这不能直接实现,是否有任何解决方法或技巧?

我认为这不会按原样编译。一方面,System.out.println 不会抛出 InterruptedException。我认为您错误地认为调用 threadB.interrupt() 会导致 threadB 抛出 InterruptedException。但它不会:它只会设置中断标志。请记住,InterruptedException 是一个已检查的异常:它不会凭空出现,必须抛出它。

那么,撇开这个不谈,你的例子与实际情况有多接近?

如果您一般需要知道“谁设置了我的中断标志”,我认为没有任何直接的方法可以知道这一点。如果您真的非常需要知道这一点,您可以使用 Aspect4J 之类的东西,并在 interrupt() 方法中加入建议以保存该信息。

但是如果你对你的代码有更多的控制权(如上例所示),答案是使用对象封装并且让 B 不直接中断 A,而是调用一个这样做的方法。真的,我认为无论如何这是更好的做法,因为它让您自己的代码在中断的情况下做它需要做的事情。这没有经过测试,但就是这个想法:

static class MyThread extends Thread {
  String interrupter;

  public void interrupt(String interrupter) {
    this.interrupter = interrupter;
    super.interrupt();
  }

  public void run() {
    while (!this.isInterrupted()) {
      // Do the thing
    }
    // Here you can see who interrupted you and do whatever
  }
}