Как приостановить и возобновить тему в Java? - PullRequest
0 голосов
/ 02 мая 2020

Я создаю программу, которая включает камеру моего ноутбука, эта программа обрабатывает потоки в Java, я пытаюсь приостановить поток, чтобы разрешить выполнение другого потока, используя toggleButton, но я вижу, что методы suspend () и resume () неясны, я хотел бы знать, как я могу обработать эти потоки.

Это мой класс, который создает первый поток и позволяет мне активировать камеру на моем ноутбуке

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;
    }
}

Это мой другой класс, тот, который позволяет вам изменить цвет изображения, я ищу, чтобы иметь возможность приостановить поток 1, который запускает класс Video, и запустить поток 2, который запускает класс VideoGray

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;
    }
}

Это то, что у меня есть в моем ToggleButton переменная vd принадлежит классу, созданному до Video, а переменная vdg принадлежит классу VideoGray, созданному в начале основного класса, переменная vd настроена на запуск в начале основного класса чтобы при запуске программы она запускалась, поэтому при выборе кнопки я хочу приостановить этот поток 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();
    }



}                                              

Ответы [ 2 ]

0 голосов
/ 02 мая 2020

Вот пример обобщенного c с использованием кода, похожего на ваш:

Во-первых, класс, который создает 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();

    }

}

Теперь * Класс 1006 *, выполняющий эту работу:

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;
    }
}

Вот пример выходных данных:

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 Учебник по параллелизму для получения более подробной информации.

0 голосов
/ 02 мая 2020

В ваших темах:

} 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...