为了保持GUI响应,有必要在与事件派发线程不同的线程上执行长时间运行的任务,例如数据库访问。 为此,有两个主要的选择:创建SwingWorker并调用程序逻辑对象的方法(使它们交易安全!),或创建单个Thread类并将请求转发给它(如此处所示:Java desktop - how to separate database access from the UI thread?) 。 你认为哪一个以及在什么情况下是更好的方法,特别是从设计的角度来看?
答案 0 :(得分:2)
问题很广泛,没有任何重要的背景。
SwingWorker
通常是"我首选的解决方案很简单,有多种方式可以与之互动(publish
/ process
,done
,PropertyListener
)并且可以专门用于工作单位,无论是重复的工作单位还是单一的工作单位。
SwingWorker
有局限性,首先,它只允许10个同时工作的人一次运行,它使用了一个Thread
池(为简单起见)使用,但池限制为10,你无能为力。如果您预计需要进行大量并发处理,这可能是一个问题,但如果您只是想要完成工作,那么这可能不是一个大问题。并且如果某些工作排队等待一段时间,请不要关心。
使用单个Thread
和队列可以再次起作用,假设您不介意一次只完成一项工作而另一项任务可能排队一段时间。这种方法的复杂性在于设置回调过程,该过程可以使用Observer Pattern或{{{{}}之类的内容将工作Thread
的数据/结果返回给EDT上下文中的UI。 3}}以一种足够灵活的方式,SwingWorker
已经做过的事情。
我的第一个想法是,专注于创建一个可以检索数据的过程,而不必担心并发或UI。一旦你可以建立它,你就可以在它上面添加另一个并发的层,因为代码的每个方面都不关心为UI获取数据。
从那里,您可以设计访问机制,您的UI代码将根据您的需要使用这些访问机制来访问这两个其他层。
这是所有理论,整体问题的背景将决定您可能遵循哪些路径(或组合)(数据库是否支持并发访问?您想要多个/并发访问还是不关心?等等)。您可以尝试以允许您更改单个图层的方式解耦代码,而无需(显着)修改其他图层。
答案 1 :(得分:1)
您也可以使用SwingUtilities.invokeLater()