Доступ к виджетам только в потоке пользовательского интерфейса
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 на практике Брайана Гетца и др ..