[英]How interrupt/stop a thread in 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
}
所以,即使我調用方法'停止',線程也不會停止。 它保持活力。
如何中斷/停止此線程?
更新 (@little方法)
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();
}
}
中間件類:
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();
}
}
}
但是當我試圖阻止線程時,它沒有。
上面的代碼可能有什么問題?
你真的沒有理由需要使用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;
從你的while和線程將死亡,無需調用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
如果要中斷正在運行的線程,則需要訪問該線程對象。
thread = new Thread(scan);
thread.start();
然后說
thread.interrupt();
這將中斷正在運行的線程。
停止線程的常用方法是使用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()
。
完全同意Jim ..只是為了添加如果您的線程在try塊內被阻塞,例如讀取數據流等,那么也會中斷線程或關閉流。 在這兩種情況下,線程應該再次被喚醒,然后它將能夠看到“stop”布爾值的變化並且通過掉出run方法自然死亡。 至少這是我在服務器的關閉線程中殺死我的線程所做的。
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
//do something here
if(condition)
{
Thread.currentThread().interrupt();
}
}
您可以使用外部鎖定,而不是使用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();
}
}
這使您的代碼更優雅,並以更好的方式處理中斷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.