如何在中断线程 B 时识别线程 A 的名称或任何上下文信息?
How to identify name or any contextual info of thread A when it interrupts thread B?
我在类似的行中发现了一个问题:
- 如何在中断线程 B 时识别线程 A 的名称或任何上下文信息?
- 即使我们获得了线程 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.
- 这是否意味着我必须创建继承“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
}
}
我在类似的行中发现了一个问题:
- 如何在中断线程 B 时识别线程 A 的名称或任何上下文信息?
- 即使我们获得了线程 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.
- 这是否意味着我必须创建继承“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
}
}