Java Thread.stop() vs Thread.interrupt()
У меня есть следующий код:
renderThread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000000; i++) {
System.out.println("Number: " + i);
}
}
});
renderThread.start();
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
renderThread.interrupt(); //It should stop, but it does not stop.
renderThread.interrupt()
не прерывает поток, он продолжает работать. Если я заменил renderThread.interrupt()
на .stop()
, то поток остановится. Однако .stop()
устарел.
Тогда, каков правильный способ остановки потока, если stop
устарел и interrupt
не работает?
Ответы
Ответ 1
При вызове interrupt() он вызывает логический флаг, который сообщает функции запуска, которую он должен остановить. Вот почему я обычно пишу свои функции запуска следующим образом.
void run()
{
while(!Thread.interrupted())
{
//Do something
}
}
Просто потому, что вы вызываете прерывание, это не означает, что поток остановится немедленно или вообще. Это зависит от того, что находится в функции run.
Ответ 2
Чтобы действительно толкнуть точку, почему вы не должны использовать Thread.stop()
?
Недавно Дуг Лея упомянул, что Thread.stop будет первым де-реализованным методом для Java приступить к Java 8.
Его ответ на этот комментарий от кого-то:
Кроме того, синхронизируется еще одна синхронизация - она обрабатывает асинхронные прерывания потоков (I.e. thread.stop()). Я знаю, что stop() устарели и все, но вы никогда не знаете.
Был:
Но вы знаете! Начиная с JDK8, Thread.stop действительно ушел. Это первый устаревший метод, который фактически был отменен. Это сейчас просто бросает UnsupportedOperationException.
http://cs.oswego.edu/pipermail/concurrency-interest/2013-December/012028.html
Ответ 3
Вы должны взглянуть на эту статью:
http://10kloc.wordpress.com/2013/03/03/java-multithreading-steeplechase-stopping-threads/
В принципе, вы не должны останавливать поток (небезопасно), но прерывать его.
То, что вам не хватает, это заставить поток обрабатывать прерывание.
Ответ 4
Все, что вам нужно сделать, чтобы прервать текущий поток или завершить выполняющийся процесс потока, - это
добавьте инструкцию ниже в блок catch
try
{
Thread.sleep(4000);
System.out.println("VAS CONSULTING")
}
catch(InterruptedException e)
{
//Stop printing out VAS CONSULTING
return; /*This will terminate the thread*/
}
также, если метод, который не выдает прерывание, не используется в методе запуска
вы можете сделать это для обработки прерывания потока или прекращения потока
@Override
public void run()
{
System.out.println("VAS CONSULTING");
if(Thread.Interrupted())
{
doSomethingElse();//process something else within the thread
return; //Terminates the current Thread
}
}
Я надеюсь, что это поможет вам или кому-то еще.
Ответ 5
renderThread.interrupt() не прерывает поток, он продолжается для запуска.
- Если поток выполняется и
interrupt()
вызывается, он устанавливает статус прерывания.
- Если этот поток заблокирован при вызове одного из методов
wait
класса Object или методов Thread.join
и Thread.sleep
этого класса, тогда его статус прерывания будет очищен, и он получит InterruptedException
.
Например:
Thread t = new Thread()
{
public void run()
{
try {
for(int i=0; i<10000;i++)
System.out.println("Is interrupTed? "+this.isInterrupted());
Thread.sleep(200);
} catch (InterruptedException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
}
};
t.start();
t.interrupt();
}
В приведенном выше коде я использовал цикл for
, чтобы перехватить флаг interrput с помощью isInterrupted()
и распечатать его. При вызове t.interrupt()
isInterrupted()
вернет true
, который вы увидите в консоли. Как только он достигнет Thread.sleep(miliTime)
, вы увидите, что InterruptedException
пойман, который был выброшен, как описано выше.
Остановка потока:
вы можете использовать этот флажок isInterrupted()
, если на него был вызван interrupt()
и вернуться из выполнения:
Например:
Thread t = new Thread()
{
public void run()
{
long executeTime = System.currentTimeMillis() ;
int i = 0;
for(; i<10000 && !this.isInterrupted();i++)
System.out.println("Is interrupted? "+this.isInterrupted());
System.out.println("Was Interrupted? "+this.isInterrupted()
+" after cycle: "+ i);
System.out.println("Time it gets Executed: "
+(System.currentTimeMillis() - executeTime+" ms"));
}
};
t.start();
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
t.interrupt();
При запуске приведенного выше кода: я отправил основной поток в режим сна для 200
внутри статической основной функции, чтобы запустить запущенный поток t
для запуска в течение некоторого времени. Затем я вызвал
t.interrupt()
на нем, который заставляет цикл for
останавливаться и печатать вывод следующим образом:
Was Interrupted? true after cycle: 1477
Time it gets Executed: 258 ms
Что указывает, что цикл for
имеет 1148
итерацию до t.interrupt();
в функции main
.
Подробнее см. документацию Thread.interrupt()
.
Ответ 6
Метод interrupt() не останавливает Thread.
прочитайте это для более подробного объяснения http://www.ibm.com/developerworks/java/library/j-jtp05236/