繁体   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