Thread currentThread=Thread.currentThread();
public void run()
{
while(!shutdown)
{
try
{
System.out.println(currentThread.isAlive());
Thread.interrupted();
System.out.println(currentThread.isAlive());
if(currentThread.isAlive()==false)
{
shutdown=true;
}
}
catch(Exception e)
{
currentThread.interrupt();
}
}
}
});
thread.start();
Как я могу убить поток? без использования stop();
Ответ 1
Альтернативой вызову stop является использование прерывания для подачи сигнала в поток, который вы хотите, чтобы он завершил то, что он делает. (Это предполагает, что поток, который вы хотите остановить, хорошо себя ведет, если он игнорирует InterruptedExceptions, поедая их сразу же после их броска и не проверяя прерванный статус, тогда вы возвращаетесь к использованию stop().)
Вот код, который я написал как ответ на вопрос о потоке здесь, это пример того, как работает прерывание потока:
public class HelloWorld {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(5000);
System.out.println("Hello World!");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
thread.start();
System.out.println("press enter to quit");
System.in.read();
thread.interrupt();
}
}
Некоторые вещи, о которых нужно знать:
-
Прерывание вызывает
sleep()
иwait()
для немедленного броска, иначе вы застряли в ожидании времени сна. -
Обратите внимание, что нет необходимости в отдельном булевом флаге.
-
Прекращающийся поток взаимодействует, проверяя прерванный статус и перехватывая InterruptedExceptions вне цикла while (используя его для выхода из цикла). Прерывание - это одно место, где можно использовать исключение для управления потоком, вот и все.
-
Настройка прерывания по текущему потоку в блоке catch является технически лучшей практикой, но для этого примера излишняя, потому что больше нет необходимости устанавливать флаг прерывания.
Некоторые замечания о размещенном коде:
-
Опубликованный пример неполный, но ссылка на текущий поток в переменной экземпляра кажется плохой идеей. Он будет инициализирован любым потоком, создающим объект, а не потоком, выполняющим метод run. Если один и тот же экземпляр Runnable выполняется более чем в одном потоке, переменная экземпляра не будет отражать правильный поток большую часть времени.
-
Проверка наличия живого потока всегда обязательно приведет к истинному (если нет ошибки, когда переменная экземпляра currentThread ссылается на неправильный поток),
Thread#isAlive
является ложным только после завершения потока он не возвращает false только потому, что он был прерван. -
Вызов
Thread#interrupted
приведет к очистке флага прерывания и не имеет смысла здесь, тем более, что возвращаемое значение отбрасывается. Точка вызоваThread#interrupted
- проверить состояние прерванного флага, а затем очистить его, это метод удобства, используемый вещами, которые бросаютInterruptedException
.
Ответ 2
Как правило, поток прерывается, когда прерывается. Итак, почему бы не использовать native boolean? Попробуйте isInterrupted():
Thread t = new Thread(new Runnable(){
@Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
// do stuff
}
}});
t.start();
// Sleep a second, and then interrupt
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
t.interrupt();
Ответ 3
Хорошим способом сделать это было бы использование булевского флага для передачи потока.
class MyRunnable implements Runnable {
public volatile boolean stopThread = false;
public void run() {
while(!stopThread) {
// Thread code here
}
}
}
Создайте экземпляр MyRunnable с именем myrunnable, оберните его в новый экземпляр Thread
и запустите экземпляр. Когда вы хотите пометить поток для остановки, установите myrunnable.stopThread = true. Таким образом, он не останавливается посередине чего-то, только там, где мы ожидаем его остановки.