JavaFX зависает, когда я запускаю поток — я использую команду Runlater

#java #multithreading #gluon

#java #многопоточность #глюон

Вопрос:

У меня есть такой простой поток.

открытый класс CameraThread расширяет поток {

     private AtomicBoolean runCamera;

    public CameraThread(AtomicBoolean runCamera) {
        this.runCamera = runCamera;
    }

    @Override
    public void run() {
        while (Main.RUNTHREAD) {
            while (runCamera.get()) {
                Platform.runLater(() -> {
                    System.out.println("Hello");
                    threadSleep();
                });
            }
        }
    }

    private void threadSleep() {
        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
 

И когда я устанавливаю runCamera значение runCamera.set(true) utside из потока, весь графический интерфейс зависает, и я ничего не могу сделать.

Это минимальный пример, и я не могу заставить его работать должным образом. Я уже использовал RunLater command раньше, но на этот раз я сижу за Dell precision M6400 компьютером с 2007 года. Может ли случиться так, что эта машина не может обрабатывать потоки с помощью Java?

Или как я могу решить эту проблему?

Чтобы воспроизвести эту проблему, просто введите следующее:

 wget https://github.com/DanielMartensson/Darknet-Data-Creator/archive/main.zip
unzip Darknet-Data-Creator-main.zip
cd Darknet-Data-Creator-main
mvn javafx:run
 

Затем нажмите на Scan кнопку, выберите веб-камеру (USB, камеру ноутбука), а затем нажмите Save to folder кнопку. Просто выберите какую-нибудь произвольную папку. Затем нажмите Open camera кнопку

Ответ №1:

Проблема в том, что вы используете Thread.Sleep() inside Platform.runLater(...) , что означает, что вы используете графический интерфейс, а не поток вашей камеры.

Попробуйте это вместо этого, обратите внимание, что runLater находится за пределами Platform.runLater кода:

 @Override
public void run() {
    while (Main.RUNTHREAD) {
        while (runCamera.get()) {
            Platform.runLater(() -> {
                System.out.println("Hello");
            });
            //Now thread sleep is outside of runLater:
            threadSleep();
        }
    }
}
 

Единственное, что должно входить в runlater, — это вещи, которые напрямую меняют графический интерфейс. Любые вычисления, режим ожидания, обработка, чтение файлов и т. Д. Должны Храниться отдельно.