我有一个程序,当按我的GUI上的按钮时,可以打开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);
一旦按下GUI界面上的Jbutton,按钮上的文本将更改为“ Tracking ...”,但是该线程已结束,我想将文本更改回“ Start Tracking”。
但是,由于按钮上的文字没有变回来,所以我遇到了困难。有谁知道我该如何解决?甚至有可能吗?谢谢。
答案 0 :(得分:0)
WalletLocatorInterface.trackingButton.setText("Start Tracking"); // this does not change the text on the button
从不 与另一个线程中的Swing小部件进行交互。学习Concurrency in Swing上的Oracle教程。您有时可能会放弃它,或者可能在运行时使您的应用程序发生可怕的事情。
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)
来使代码更具自记录性,如您的Question所示。使用带池大小参数的变体向阅读程序员建议,她可以稍后在编辑代码时灵活地更改该参数。当然,也可以在代码注释中以散文形式进行解释。
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 Concurrency in Practice 由Brian Goetz等人撰写。