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();
}
}
}
Но когда я пытаюсь остановить поток, это не так. Что может быть не так в коде выше?
С наилучшими пожеланиями, Вальтер Энрике.
8 ответов
Там действительно нет причин, вам нужно использовать 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
,
Просто return;
от вашего времени и поток умрет, не нужно вызывать stop() или interrupt(). Если вы хотите сделать это извне, используйте этот шаблон и вызовите 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;
}
}
"Много использования stop()
должен быть заменен кодом, который просто изменяет некоторую переменную, чтобы указать, что целевой поток должен прекратить работу."- java.lang.Thread
Обычный способ остановить поток - иметь флаг 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()
,
Если вы хотите прервать работающий поток, вам нужен доступ к объекту потока.
thread = new Thread(scan);
thread.start();
тогда скажи
thread.interrupt();
это прервет работающий поток.
Полностью согласен с Джимом. Просто добавить. Если ваш поток заблокирован внутри блока try, например, для чтения потока данных и т. Д., То прервите поток или закройте поток. В обоих случаях поток должен быть снова пробужден, и тогда он сможет увидеть изменение значения "stop" boolean и умереть естественным образом, выпадая из метода run. По крайней мере, это то, что я сделал, чтобы убить мои потоки в ветке отключения моего сервера.
Вместо использования 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();
}
}
Это делает ваш код элегантным и лучше обрабатывает прерывания.
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
//do something here
if(condition)
{
Thread.currentThread().interrupt();
}
}