用它的方法中断 Runnable 实例
Interrupting Runnable instance with its method
假设我有 类 像那些:
Foo.java:
public class Foo implements Runnable{
public void run(){
try{
sleep(3000);
System.out.println("Slept for 3s");
}catch(InterruptedException e){
Thread.currentThread().interrupt();
System.out.println("Exception handled from Foo");
}
}
public void terminate(){
Thread.currentThread().interrupt();
}
}
Bar.java:
public class Bar implements Runnable{
private Foo f;
public Bar(Foo f){
this.f = f;
}
public void run(){
System.out.println("Interrupting Foo");
f.terminate();
System.out.println("Interrupted Foo");
try{
sleep(4000);
System.out.println("Slept for 4s");
}catch(InterruptedException e){
Thread.currentThread().interrupt();
System.out.println("Exception handled from Bar");
}
}
}
Test.java:
public class Test{
public static void main(String[] args){
Foo f = new Foo();
Bar b = new Bar(f);
new Thread(f).start();
new Thread(b).start();
System.out.println("Test end");
}
}
当我编写这段代码时,我希望输出如下:
Test end
Interrupting Foo
Exception from Foo handled
Interrupted
Slept for 4s
但我得到的不是上面的:
Test end
Interrupting Foo
Interrupted
Exception from Bar handled
Slept for 3s
这段代码背后的故事是,在我的应用程序中,我需要一个 Thread/Runnable 来中断另一个匿名线程 运行 我有权访问的另一个 Runnable 实例。知道我可以使用 Thread.currentThread.interrupt() 从 Runnable 内部中断线程(从互联网上学到)我认为在我想停止的 Runnable 方法中调用它,然后在另一个 Thread 的实例上调用这个方法会打断它。但是如上面的示例所示,它正在中断调用该方法的线程,而不是运行定义此方法的 Runnable 的线程。我知道我对 Thread.currentThread.interrupt() 的工作方式一无所知,而且它没有像我预期的那样工作,我有几个问题:
1. 从这个例子的工作原理来看,我假设 Thread.currentThread.interrupt() 中断正在执行调用它的函数的线程,而不是 运行 调用函数的实例的线程。那正确吗?如果不是,它是如何工作的?
2.(最重要的)有没有办法通过从另一个线程调用其 Runnable 的方法来中断线程?如果是 - 它是如何完成的?如果不是 - 我是否必须有权访问 Thread 实例才能中断它,或者如果 Foo 只是扩展 Thread 而不是实现 Runnable 会更好吗?
3.为什么在sleep之前调用中断会捕获到Bar的异常?
尝试完整回答您的问题:
你是对的。正如您在此处看到的 https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html Thread.currentThread()
returns 对当前正在执行的线程的引用。
是的,有。 Android: How do I stop Runnable?
因为正如您在 1 中所建议的那样,您正在中断当前正在执行的线程,这是 Bar
上下文所在的线程。Bar
导致它自己的 InterruptedException
.
Thread.currentThread()
return 当前 运行 线程。您似乎期望有一个线程与 Foo
的实例相关联,因为它的 run()
方法几乎占据了整个 class,并且它的 terminate()
方法将然后使用那个线程,但是 Foo
只是一个普通的 class。它的 run()
方法可以被另一个以它的实例启动的线程调用,也可以直接调用。在任何情况下,当在某个线程上直接调用 terminate()
方法时,Thread.currentThread()
将 return 该线程。
thread.interrupt()
方法不一定会引发 InterruptedException
。如果线程正在休眠、等待或调用某些阻塞操作,则会发生这种情况,但文档说:
If none of the previous conditions hold then this thread's interrupt status will be set.
中断状态只是一个标志,表示线程已被中断。下次调用睡眠、等待或阻塞操作时,将立即抛出 InterruptedException
。
如果您想中断特定线程,而不是当前线程,特别是对于您已启动的线程,有一个简单的解决方案:在启动时存储对该线程的引用。
Thread fthread = new Thread(f).start();
Bar b = new Bar(f, fthread);
然后在 Bar
中调用 fthread.interrupt()
,而不是调用 f.terminate()
。
假设我有 类 像那些: Foo.java:
public class Foo implements Runnable{
public void run(){
try{
sleep(3000);
System.out.println("Slept for 3s");
}catch(InterruptedException e){
Thread.currentThread().interrupt();
System.out.println("Exception handled from Foo");
}
}
public void terminate(){
Thread.currentThread().interrupt();
}
}
Bar.java:
public class Bar implements Runnable{
private Foo f;
public Bar(Foo f){
this.f = f;
}
public void run(){
System.out.println("Interrupting Foo");
f.terminate();
System.out.println("Interrupted Foo");
try{
sleep(4000);
System.out.println("Slept for 4s");
}catch(InterruptedException e){
Thread.currentThread().interrupt();
System.out.println("Exception handled from Bar");
}
}
}
Test.java:
public class Test{
public static void main(String[] args){
Foo f = new Foo();
Bar b = new Bar(f);
new Thread(f).start();
new Thread(b).start();
System.out.println("Test end");
}
}
当我编写这段代码时,我希望输出如下:
Test end
Interrupting Foo
Exception from Foo handled
Interrupted
Slept for 4s
但我得到的不是上面的:
Test end
Interrupting Foo
Interrupted
Exception from Bar handled
Slept for 3s
这段代码背后的故事是,在我的应用程序中,我需要一个 Thread/Runnable 来中断另一个匿名线程 运行 我有权访问的另一个 Runnable 实例。知道我可以使用 Thread.currentThread.interrupt() 从 Runnable 内部中断线程(从互联网上学到)我认为在我想停止的 Runnable 方法中调用它,然后在另一个 Thread 的实例上调用这个方法会打断它。但是如上面的示例所示,它正在中断调用该方法的线程,而不是运行定义此方法的 Runnable 的线程。我知道我对 Thread.currentThread.interrupt() 的工作方式一无所知,而且它没有像我预期的那样工作,我有几个问题:
1. 从这个例子的工作原理来看,我假设 Thread.currentThread.interrupt() 中断正在执行调用它的函数的线程,而不是 运行 调用函数的实例的线程。那正确吗?如果不是,它是如何工作的?
2.(最重要的)有没有办法通过从另一个线程调用其 Runnable 的方法来中断线程?如果是 - 它是如何完成的?如果不是 - 我是否必须有权访问 Thread 实例才能中断它,或者如果 Foo 只是扩展 Thread 而不是实现 Runnable 会更好吗?
3.为什么在sleep之前调用中断会捕获到Bar的异常?
尝试完整回答您的问题:
你是对的。正如您在此处看到的 https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html
Thread.currentThread()
returns 对当前正在执行的线程的引用。是的,有。 Android: How do I stop Runnable?
因为正如您在 1 中所建议的那样,您正在中断当前正在执行的线程,这是
Bar
上下文所在的线程。Bar
导致它自己的InterruptedException
.
Thread.currentThread()
return 当前 运行 线程。您似乎期望有一个线程与 Foo
的实例相关联,因为它的 run()
方法几乎占据了整个 class,并且它的 terminate()
方法将然后使用那个线程,但是 Foo
只是一个普通的 class。它的 run()
方法可以被另一个以它的实例启动的线程调用,也可以直接调用。在任何情况下,当在某个线程上直接调用 terminate()
方法时,Thread.currentThread()
将 return 该线程。
thread.interrupt()
方法不一定会引发 InterruptedException
。如果线程正在休眠、等待或调用某些阻塞操作,则会发生这种情况,但文档说:
If none of the previous conditions hold then this thread's interrupt status will be set.
中断状态只是一个标志,表示线程已被中断。下次调用睡眠、等待或阻塞操作时,将立即抛出 InterruptedException
。
如果您想中断特定线程,而不是当前线程,特别是对于您已启动的线程,有一个简单的解决方案:在启动时存储对该线程的引用。
Thread fthread = new Thread(f).start();
Bar b = new Bar(f, fthread);
然后在 Bar
中调用 fthread.interrupt()
,而不是调用 f.terminate()
。