Как только запланированный пул потоков закончен, измените текст JButton - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть программа, которая открывает считыватели RFID при нажатии кнопки на моем графическом интерфейсе.Это все отлично работает.Я использую ScheduledThreadPool для закрытия считывателей RFID через определенное время, как показано ниже:

Executors.newScheduledThreadPool(1).schedule(() -> {
        try {
            phid1.close();
            phid2.close();
        } catch (PhidgetException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        WalletLocatorInterface.infoTextArea.append("\nClosed RFIDs\n\n");
        WalletLocatorInterface.infoTextArea.append("Final Wallet Locations:\n");          
        try {
            getLocations();
        } catch (SQLException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        WalletLocatorInterface.trackingButton.setText("Start Tracking"); // this does not change the text on the button
    }, TimeOptionWindow.getTime(), TimeUnit.SECONDS);

После нажатия кнопки J на ​​интерфейсе графического интерфейса текст на кнопке изменяется на «Отслеживание ...»Тем не менее, один поток закончился, я хочу изменить текст обратно на «Начать отслеживание».

Однако у меня возникли трудности, так как текст на кнопке не меняется обратно.Кто-нибудь знает, как я мог бы это исправить?или это вообще возможно?Спасибо.

1 Ответ

0 голосов
/ 18 февраля 2019

Доступ к виджетам только в потоке пользовательского интерфейса

WalletLocatorInterface.trackingButton.setText("Start Tracking"); // this does not change the text on the button 

Никогда не взаимодействует с виджетами Swing из другого потока.Изучите руководство Oracle по Параллелизму в Swing .Вы можете сойти с рук по этому случаю, или вы можете вызвать ужасные вещи с вашим приложением во время выполнения.

Сохранять вашего исполнителя

Executors.newScheduledThreadPool(1).schedule( 

Не создавать экземпляры пула потоков и каждого исполнителяраз у вас есть задача под рукой.Держите исполнителя.В большинстве ситуаций вы хотели бы сохранить один и тот же объект-исполнитель для всего запуска вашего приложения.Вызывайте метод исполнителя schedule несколько раз, каждый раз, когда у вас есть работа.Попробуйте использовать несколько потоков в вашем пуле, а не один, в зависимости от ваших потребностей.

Каждый раз, когда вы вызываете Executors.newScheduledThreadPool(1), вы создаете экземпляр другого исполнителя с другим пулом потоков (из одного потока).Сделайте это три раза, и у вас будет три исполнителя, каждый из которых имеет пул из одного потока, всего три потока.Вместо этого создайте экземпляр исполнителя, поддерживаемого одним пулом потоков из трех потоков.Затем отправьте ряд задач этому исполнителю.Представленные задачи будут выполняться в любом из трех потоков, так как это задача исполнителя: назначить задачи потокам.

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool​​( 3 ) ; // Keep around a reference to this executor service.
… // Do some other stuff
scheduledExecutorService.schedule( () -> { System.out.println( "Eat early breakfast." ) } , … ) ;
… // Do some other stuff
int snacksCount = 3 ;
for( int i = 1 ; i <= snacksCount ; I ++ ) {
   scheduledExecutorService.schedule( () -> { System.out.println( "Eat snack." ) }  , … ) ;
}
… // Do some other stuff
scheduledExecutorService.schedule( () -> { System.out.println( "Eat lunch." ) }  , … ) ;
… // Do some other stuff
scheduledExecutorService.schedule( () -> { System.out.println( "Eat dinner." ) }  , … ) ;
… // Do some other stuff
scheduledExecutorService.shutdown() ;  // Always shut down your executor service. Otherwise, its pool of threads may continue indefinitely, even beyond the run of your app. 

Важно: Обратите внимание, что в нескольких потокахиграть, запланированные задачи могут не выполняться в представленном порядке.Например, ужин можно съесть до обеда.Если порядок важен, используйте однопотоковый пул.

Если вы по этой причине используете однопотоковый пул, сделайте свой код более самодокументированным, вызвав Executors.newSingleThreadScheduledExecutor() вместо Executors.newScheduledThreadPool(1), как видно наваш вопрос.Использование варианта с аргументом размера пула подсказывает читающему программисту, что он может безболезненно изменить этот аргумент позже при редактировании кода.И, конечно же, объясните в прозе в комментарии к коду.

ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor() ; // *Must* use only a *single* thread pool, to ensure our meal-eating tasks execute in the order they were submitted. 

К вашему сведению: Параллельное программирование очень сложно .В конце концов я предлагаю прочитать Параллелизм Java на практике Брайана Гетца и др ..

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