簡體   English   中英

如何在 Java 中暫停和恢復線程?

[英]How to pause and resume a Thread in Java?

我正在創建一個打開筆記本電腦攝像頭的程序,該程序處理 Java 中的線程,我試圖暫停一個線程以允許另一個線程使用切換按鈕執行,但我看到掛起()恢復()的方法晦澀難懂,我想知道如何處理這些線程。

這是我的 class 創建第一個線程並允許我激活筆記本電腦上的相機

class Video extends Thread {

    boolean Running = true;

    @Override
    public void run() {

        while (this.Running) {
            Image image = webcam.getImage();
            jLabel1.setIcon(new ImageIcon(image));
            try {
                Thread.sleep(30);
            } catch (InterruptedException ex) {
                Logger.getLogger(WebCam.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void kill() {
        this.Running = false;
    }
}

這是我的另一個 class,它允許您更改圖像的顏色,我正在尋找的是能夠暫停運行視頻 class 的線程 1 並啟動運行 VideoGray ZA2F2ED4F8EBC2CBB4C21A29DZ 的線程 2

class VideoGray extends Thread {

    boolean Running = true;

    @Override
    public void run() {

        while (this.Running) {
            BufferedImage src = webcam.getImage();
            ColorConvertOp op
                    = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
            BufferedImage dest = op.filter(src, null);

            jLabel1.setIcon(new ImageIcon(dest));
            try {
                Thread.sleep(20);

            } catch (InterruptedException ex) {
                Logger.getLogger(WebCam.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void kill() {
        this.Running = false;
    }
}

This is what I have in my ToggleButton, the vd variable belongs to the class created before Video and the vdg variable belongs to the VideoGray class created at the beginning of the main class, the vd variable is set to run at the beginning of the class main 這樣當你運行程序時它就會啟動,所以當我 select 按鈕時,我想暫停那個 vd 線程並使 vdg 線程運行。

private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                               
    // TODO add your handling code here:

    System.out.println(jToggleButton1.isSelected());

    if (jToggleButton1.isSelected()) {
            vd.suspend();
            vdg.resume();
    }



}                                              

在您的線程中:

} catch (InterruptedException ex) {
    Logger.getLogger(WebCam.class.getName()).log(Level.SEVERE, null, ex);
    return; // This terminates thread execution.
}

在您的切換按鈕操作中:

vd.interrupt();
vdg.start();

很好的教程: https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

這是一個使用與您類似的代碼的通用示例:

首先,一個 class 創建 2 個額外的線程,暫停和恢復它們:

public class PauseThreadMain {

    public static void main(String[] args) throws InterruptedException {
        Runner r = new Runner();
        Thread t = new Thread(r);
        t.start(); //first runner active

        Runner r2 = new Runner();
        Thread t2 = new Thread(r2);

        Thread.sleep(1250);
        r.togglePause(); //first runner paused
        t2.start(); //second runner active

        Thread.sleep(1250);
        r2.togglePause(); //second runner paused, first runner also paused
        Thread.sleep(1250);
        r.togglePause(); //first runner active

        //After some time stop both threads.
        Thread.sleep(1250);
        t.interrupt();
        t2.interrupt();

    }

}

現在執行工作的Runner class:

public class Runner implements Runnable{
    boolean running = false, paused = false;

    @Override
    public void run() {
        running = true;

        while (this.running) {
            if(paused){
                System.out.println(Thread.currentThread().getName()+" is paused");
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e) {
                    return;
                }
                continue;
            }
            System.out.println(Thread.currentThread().getName()+" is doing some work");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                return;
            }
        }
    }

    public void kill() {
        this.running = false;
    }

    public void togglePause(){
        paused = !paused;
    }
}

這是一些示例 output:

Thread-0 is doing some work
Thread-0 is doing some work
Thread-1 is doing some work
Thread-0 is paused
Thread-1 is doing some work
Thread-0 is paused
Thread-0 is paused
Thread-0 is paused
Thread-0 is paused
Thread-1 is paused
Thread-0 is paused
Thread-1 is paused
Thread-0 is paused
Thread-1 is paused
Thread-0 is doing some work
Thread-1 is paused
Thread-1 is paused
Thread-1 is paused
Thread-1 is paused
Thread-0 is doing some work

最后,請注意,這種方法不保證任何發生之前的關系。 即使在您調用togglePause之后,線程也可能會繼續執行一段時間,因為它會定期檢查paused變量 - 如果它已經檢查過這個標志,在我的示例中它不會再檢查一次 250 毫秒。

您可以閱讀Java 並發教程了解更多詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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