GUI应用程序(Java、swing)中线程的最佳方法
为了保持GUI的响应性,有必要在不同于事件调度线程的线程上执行长时间运行的任务,例如数据库访问。 为此,有两种主要的替代方法:创建SwingWorker并调用程序逻辑对象的方法(使其交易安全!),或者创建单个线程类并将请求转发给它(如本文所建议的:)。GUI应用程序(Java、swing)中线程的最佳方法,java,multithreading,swing,Java,Multithreading,Swing,为了保持GUI的响应性,有必要在不同于事件调度线程的线程上执行长时间运行的任务,例如数据库访问。 为此,有两种主要的替代方法:创建SwingWorker并调用程序逻辑对象的方法(使其交易安全!),或者创建单个线程类并将请求转发给它(如本文所建议的:)。 特别是从设计的角度来看,你认为哪一种以及在什么情况下是更好的方法?你也可以使用SwingUtilities.invokeLater()你也可以使用SwingUtilities.invokeLater()你也可以使用SwingUtilities.i
特别是从设计的角度来看,你认为哪一种以及在什么情况下是更好的方法?你也可以使用SwingUtilities.invokeLater()你也可以使用SwingUtilities.invokeLater()你也可以使用SwingUtilities.invokeLater()你也可以使用SwingUtilities.invokeLater()这个问题涉及面很广,没有任何重要的背景
SwingWorker
通常是我首选的解决方案,因为它简单,有多种方式可以与之交互(发布
/过程
,完成
,属性链接
),并且可以专门用于工作单元,无论是重复的工作单元还是单个运行案例
SwingWorker
有一些限制,首先,它一次只允许同时运行10个工作线程,它使用了一个重复使用的Thread
s池(为简单起见),但池被限制为10个,您对此无能为力。如果您预期需要进行大量并发处理,这可能是一个问题,但如果您只是“希望完成工作”,而不关心某些工作是否排队等待一段时间,这可能不是一个大问题
假设您不介意一次只完成一项工作,而另一项任务可能会排队一段时间,那么使用单个线程和队列也可以工作。这种方法的复杂性在于设置回调过程,该过程可以在EDT的上下文中将workerThread
的数据/结果返回到UI,使用类似于或的方式,对您来说足够灵活,SwingWorker
已经做到了这一点
我的第一个想法是,专注于创建一个可以检索数据的流程,而不必担心并发性或UI。一旦建立了该层,就可以在其上添加另一个并发层,因为并非代码的每个方面都关心为UI获取数据
在此基础上,您可以设计访问机制,UI代码将根据您的需要使用这些机制访问这两个其他层
这都是理论,整个问题的背景将决定您可能遵循的路径(或组合)(数据库是否支持并发访问?您想要多个/并发访问还是不关心?等等)。您可以尝试将代码解耦,使您可以在不必(显著)修改其他层的情况下更改单个层。这个问题涉及面很广,没有任何重要的上下文
SwingWorker
通常是我首选的解决方案,因为它简单,有多种方式可以与之交互(发布
/过程
,完成
,属性链接
),并且可以专门用于工作单元,无论是重复的工作单元还是单个运行案例
SwingWorker
有一些限制,首先,它一次只允许同时运行10个工作线程,它使用了一个重复使用的Thread
s池(为简单起见),但池被限制为10个,您对此无能为力。如果您预期需要进行大量并发处理,这可能是一个问题,但如果您只是“希望完成工作”,而不关心某些工作是否排队等待一段时间,这可能不是一个大问题
假设您不介意一次只完成一项工作,而另一项任务可能会排队一段时间,那么使用单个线程和队列也可以工作。这种方法的复杂性在于设置回调过程,该过程可以在EDT的上下文中将workerThread
的数据/结果返回到UI,使用类似于或的方式,对您来说足够灵活,SwingWorker
已经做到了这一点
我的第一个想法是,专注于创建一个可以检索数据的流程,而不必担心并发性或UI。一旦建立了该层,就可以在其上添加另一个并发层,因为并非代码的每个方面都关心为UI获取数据
在此基础上,您可以设计访问机制,UI代码将根据您的需要使用这些机制访问这两个其他层
这都是理论,整个问题的背景将决定您可能遵循的路径(或组合)(数据库是否支持并发访问?您想要多个/并发访问还是不关心?等等)。您可以尝试将代码解耦,使您可以在不必(显著)修改其他层的情况下更改单个层。这个问题涉及面很广,没有任何重要的上下文
SwingWorker
通常是我首选的解决方案,因为它简单,有多种方式可以与之交互(发布
/过程
,完成
,属性链接
),并且可以专门用于工作单元,无论是重复的工作单元还是单个运行案例
SwingWorker
有一些限制,首先,它一次只允许同时运行10个工作线程,它使用了一个重复使用的Thread
s池(为简单起见),但池被限制为10个,您对此无能为力。如果您预期occ需要大量并发处理,那么这可能是一个问题