Допустим, у меня есть такие классы: 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
За этим кодом стоит история о том, что в моем приложении мне нужен одинПоток / Runnable для прерывания другого анонимного потока, выполняющего другой экземпляр Runnable, к которому у меня есть доступ.Зная, что я могу прервать поток из Runnable изнутри с помощью Thread.currentThread.interrupt () (узнал из Интернета), я подумал, что, вызывая это в методе Runnable, я хочу остановить его, а затем вызывая этот метод в его экземпляре в другом потоке.прервет это.Но, как показано в приведенном выше примере, он прерывает поток, который вызвал метод, а не поток, который выполняет Runnable, в котором определен этот метод.Зная, что я ничего не знаю о том, как Thread.currentThread.interrupt () работает и что он не работает, как я ожидал, у меня есть несколько вопросов:1. Из того, как работает этот пример, я предполагаю, что Thread.currentThread.interrupt () прерывает поток, выполняющий функцию, в которой он вызывается, а не тот, который выполняет экземпляр, в котором была вызвана функция.Это правильно?Если нет, то как это работает?2. (самое главное) Есть ли способ прервать поток, вызвав метод его Runnable из другого потока?Если да - как это сделать?Если нет - должен ли я иметь доступ к экземпляру Thread, чтобы прервать его, или было бы лучше, если бы Foo просто расширил Thread вместо реализации Runnable?3. Почему ловится исключение из Bar, если прерывание вызывается перед сном?