簡體   English   中英

如何在Java中斷/停止線程?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM