Java 计划线程池完成后,更改JButton的文本

Java 计划线程池完成后,更改JButton的文本,java,swing,Java,Swing,我有一个程序,当按下GUI上的一个按钮时,它会打开RFID阅读器。这一切都很好。我使用ScheduledThreadPool在特定时间后关闭RFID读卡器,如下所示: Executors.newScheduledThreadPool(1).schedule(() -> { try { phid1.close(); phid2.close(); } catch (PhidgetException e1) {

我有一个程序,当按下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,按钮上的文本将更改为“跟踪…”,但是线程已结束,我想将文本更改回“开始跟踪”

然而,我有困难,因为按钮上的文本没有改变回来。有人知道我该怎么解决这个问题吗?或者甚至有可能吗?谢谢。

仅在用户界面线程中访问小部件 从不与来自另一个线程的Swing小部件进行交互。学习上的Oracle教程。有时你可能会侥幸逃脱,也可能会在运行时给你的应用程序带来可怕的后果

保留你的遗嘱执行人 不要每次手头有任务时都实例化线程池和执行器。让遗嘱执行人留在身边。在大多数情况下,您可能希望在整个应用程序运行期间保留相同的executor对象。每次有工作要做时,重复调用执行者的
计划
方法一次。考虑在您的池中使用多个线程,而不是一个,取决于您的需要。
每次调用
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. 
仅供参考:并发编程非常棘手。最后,我建议阅读
由Brian Goetz等人撰写。

好的,谢谢,所有的好信息。我不知道你所说的“保持执行器在身边”是什么意思。你能给我解释一下吗?@henry434我添加了更多的散文和代码示例来展示如何使用变量来保存对实例化执行器服务的引用。然后我们多次调用该执行器服务-同一个执行器服务,而不是每个任务的新执行器服务。
Executors.newScheduledThreadPool(1).schedule( 
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. 
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor() ; // *Must* use only a *single* thread pool, to ensure our meal-eating tasks execute in the order they were submitted.