Как прервать/остановить поток в Java?
Я пытаюсь остановить поток, но я не могу этого сделать:
public class Middleware {
public void read() {
try {
socket = new Socket("192.168.1.8", 2001);
// code ..
Scan scan = new Scan();
thread = new Thread(scan);
thread.start();
} catch (UnknownHostException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
class Scan extends Thread {
public void run() {
while (true) {
try {
// my code goes here
} catch (IOException ex) {
thread.currentThread().interrupt();
}
}
}
}
public void stop() {
Thread.currentThread().interrupt();
}
// get and setters
}
Поэтому, даже когда я вызываю метод stop, поток не останавливается. Это поддерживает жизнь.
Как я могу прервать/остановить эту тему?
ОБНОВЛЕНИЕ (@маленький подход)
private void tb_startActionPerformed(java.awt.event.ActionEvent evt) {
Middleware middleware = new Middleware();
if (tb_start.getText().equals("Start")){
tb_start.setText("Stop");
// starting to read rfid tags
middleware.read();
}else{
tb_start.setText("Start");
// stop reading rfid tags
middleware.stop();
}
}
Класс Middleware:
public class Middleware {
private Scan scan;
public void read() {
scan = new Scan();
scan.start();
}
private class Scan extends Thread {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("reading...");
}
}
}
public void stop() {
if (scan != null) {
scan.interrupt();
}
}
}
Но когда я пытаюсь остановить поток, это не так.
Что может быть не так в коде выше?
Ответы
Ответ 1
Нет причин, по которым вам нужно использовать флаг volatile
. Вместо этого просто запросите поток для его состояния с помощью isInterrupted()
. Кроме того, почему вы обертываете свой объект потока Scan
в другой объект потока? Это кажется мне совершенно ненужным.
Вот что вы должны делать
public class Middleware {
private Scan scan;
public void read() {
try {
// do stuff
scan = new Scan();
scan.start();
} catch (UnknownHostException ex) {
// handle exception
} catch (IOException ex) {
// handle exception
}
}
private class Scan extends Thread {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
// my code goes here
} catch (IOException ex) {
Thread.currentThread().interrupt();
}
}
}
}
public void stop() {
if(scan != null){
scan.interrupt();
}
}
}
Вот пример . Кроме того, я бы не рекомендовал расширять Thread
.
Ответ 2
Просто return;
от вашего времени, и поток умрет, нет необходимости вызывать stop() или прерывание(). Если вы хотите сделать это извне, используйте этот шаблон и вызовите requestStop()
.
class Scan extends Thread {
private volatile stop = false;
public void run() {
while (!stop) {
try {
// my code goes here
} catch (IOException ex) {
stop = true;
}
}
}
public void requestStop() {
stop = true;
}
}
Ответ 3
"Многие виды использования stop()
должны быть заменены кодом, который просто модифицирует некоторую переменную, указывая на то, что целевой поток должен прекратиться." - java.lang.Thread
Ответ 4
если вы хотите прервать работающий поток, вам нужен доступ к объекту потока.
thread = new Thread(scan);
thread.start();
тогда скажи
thread.interrupt();
это прервет работающий поток.
Ответ 5
Обычный способ остановить поток - иметь флаг volatile, а затем проверить его в методе run. то есть.
class Scan extends Thread {
volatile stop = false;
public void run() {
while (!stop) {
try {
// my code goes here
} catch (IOException ex) {
thread.currentThread().interrupt();
}
}
}
public void stop(){
stop = true;
}
}
Затем вы можете вызвать scan.stop()
.
Ответ 6
Полностью согласен с Jim.. Просто добавьте Если ваш поток заблокирован внутри блока try
например, чтение на потоке данных и т.д., затем прерывать поток, а также закрыть
поток. В обоих случаях поток должен быть пробужден снова, и тогда он сможет увидеть изменение значения "stop" boolean и умереть естественным путем, выпадая из метода run. По крайней мере, это то, что я сделал, чтобы убить мои потоки в потоке shutdown для моего сервера.
Ответ 7
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
//do something here
if(condition)
{
Thread.currentThread().interrupt();
}
}
Ответ 8
Вместо использования Thread.stop() или Thread.interrupt() вы можете использовать внешние блокировки. В основном, когда вы пытаетесь использовать встроенную блокировку большую часть времени, любое прерывание, которое вы выполняете в потоке, не поддается контролю.
Блокировка повторного входа предоставляет вам методы, указанные ниже.
lock()
unlock()
tryLock()
lockInterruptibly()
isHeldByCurrentThread()
getHoldCount()
Проверьте приведенный ниже пример
final ReentrantLock reentrantLock = new ReentrantLock();
@Override
public void performTask() {
reentrantLock.lock();
try {
System.out.println(Thread.currentThread().getName() + ": Lock acquired.");
System.out.println("Processing...");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + ": Lock released.");
reentrantLock.unlock();
}
}
Это делает ваш код элегантным и лучше обрабатывает прерывание.