中断Runnable实例及其方法

问题描述 投票:0回答:2

假设我有类似的课程: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.currentThread.interrupt()(从Internet上学习)从Runnable内部中断线程时,我认为我想停止在Runnable的方法中调用此方法,然后在另一个Thread的实例中调用此方法会打断它。但是如上面的示例所示,它正在中断调用该方法的线程,而不是运行定义该方法的Runnable的线程。知道我对Thread.currentThread.interrupt()的工作方式一无所知,并且无法正常工作时,我有几个问题:1.从本示例的工作方式来看,我假设Thread.currentThread.interrupt()中断了正在执行调用该函数的线程的线程,而不是正在运行该函数调用其实例的线程。那正确吗?如果没有,它如何运作?2.(最重要的)是否可以通过从另一个线程调用其Runnable的方法来中断线程?如果是,怎么办?如果不是-我是否必须访问Thread实例才能中断它,或者如果Foo只是扩展Thread而不是实现Runnable会更好?3.如果在睡眠之前调用了中断,为什么会捕获到Bar的异常?

java multithreading interrupt runnable
2个回答
0
投票

要尝试完全回答您的问题:

  1. 您是对的。如您所见,https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html Thread.currentThread()返回对当前执行线程的引用。

  2. 是的。 Android: How do I stop Runnable?

  3. 因为按照您在1.中的建议,您正在中断当前正在执行的线程,该线程是Bar上下文所在的线程。Bar导致了它自己的InterruptedException


0
投票

Thread.currentThread()返回当前正在运行的线程。您似乎期望与Thread.currentThread()实例相关联的线程,因为其Foo方法几乎占据了整个类,因此run()方法将使用该线程,但是terminate()为只是一个普通的班级。它的Foo方法可以由已使用其实例启动的其他线程调用,也可以直接调用。无论如何,当直接在某个线程上调用run()方法时,terminate()将返回该线程。

Thread.currentThread()方法不一定会引发thread.interrupt()。如果线程正在休眠,等待或调用某些阻止操作,则会发生这种情况,但是文档中说:

如果以上条件均不成立,则将设置该线程的中断状态。

中断状态只是一个标志,指示线程已被中断。下次调用睡眠,等待或阻止操作时,将立即抛出thread.interrupt()

如果要中断特定线程而不是当前线程,特别是对于已启动的线程,则有一个简单的解决方案:在启动线程时存储对该线程的引用。

InterruptedException

然后在InterruptedException中,而不是调用Thread fthread = new Thread(f).start(); Bar b = new Bar(f, fthread); ,而是调用Bar

© www.soinside.com 2019 - 2024. All rights reserved.