#multithreading #thread-sleep
#многопоточность #поток-сон
Вопрос:
Поток выполняет задачу по печати чисел от 0 до n и переходит в спящий режим в течение 4000 мс после каждого оператора печати. Где-то в середине поток прерывается. Теперь, когда тот же поток начнет свое выполнение, с чего он начнется, начнет ли он снова печатать числа от 0 до n или он будет печатать числа с того места, где он был прерван. В обоих случаях каковы причины и как это обрабатывается?
public class Main {
public static void main(String[] args) throws InterruptedException {
SleepTest sleepTest = new SleepTest();
Thread thread = new Thread(sleepTest);
thread.start();
thread.interrupt();
}
}
public class SleepTest implements Runnable{
static int sleep = 10;
public void run(){
for (int i =0; i<10; i ){
System.out.println(i);
try {
Thread.currentThread().interrupt();
Thread.sleep(4000);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
System.out.println(Thread.interrupted());
}
}
Ответ №1:
Вызов a interrupt()
для объекта потока может только предложить потоку остановиться. Это не гарантирует, что поток остановится.
Это полностью зависит от реализации run()
метода потока.
В вашем случае run()
вы перехватываете InterruptedException
и печатаете трассировку исключения, но не останавливаете поток. Вот почему поток никогда не остановится InterruptedException
и не продолжит выполнение.
Может показаться, что поток останавливается (при просмотре трассировки исключения), когда отображается вывод на консоль.
Ответ №2:
Все Thread.currentThread().interrupt()
, что нужно, это обновить значение поля interrupted
до true
.
Давайте посмотрим, как работает программа и как interrupted
полю присваиваются значения:
public class Main {
public static void main(String[] args) throws InterruptedException {
SleepTest sleepTest = new SleepTest();
Thread thread = new Thread(sleepTest, "Sub Thread"); // Give a name to this thread
thread.start(); // main thread spawns the "Sub Thread". Value of "interrupted" - false
thread.interrupt(); // called by main thread. Value of "interrupted" - true
}
}
public class SleepTest implements Runnable{
static int sleep = 10;
public void run(){
System.out.println(Thread.currentThread().getName() " " Thread.interrupted()); // prints "Sub Thread true"
for (int i =0; i<10; i ){
System.out.println(i);
try {
Thread.currentThread().interrupt(); // no matter what value is for interrupted, it is assigned the value "true"
Thread.sleep(4000); // Can't call sleep with a "true" interrupted status. Exception is thrown. Note that, when the exception is thrown, the value of interrupted is "reset", i.e., set to false
} catch (InterruptedException exception) {
exception.printStackTrace(); // whatever
}
System.out.println(Thread.interrupted()); // returns the value of interrupted and resets it to false
}
}
Чтобы ответить
с чего он начнется, начнет ли он снова печатать числа от 0 до n или будет печатать числа с того места, где он был прерван.
Вызов прерывания не приведет к его началу заново, потому что все, что он делает при этом вызове, — это устанавливает значение interrupted
false (и не изменяет ничего другого).