当然,所有这些方法都会奏效,但我希望对哪一种方法最好的意见表示感谢。
考虑一下(不幸的)场景,在这种场景中,UI更改代码和合理密集的(平均500‘s)逻辑代码混合在一起,不可分离的。所有更改的ui组件都在一个面板上。
01 new Thread(){
02 public void run(){
03
04 for (int i = 0; i < 100; i++){
05 // some processing
06 doSomething();
07 // update some ui components
08 panel.doSomeUi();
09 }
10
11 panel.revalidate();
12 panel.repaint();
13
14 }}.start();您会选择下列三种方法中的哪一种?为什么?
我的:
选项1将在所有处理发生时挂起事件处理线程(EPT)。
选项2需要考虑开销,创建了许多新的运行表,在特殊情况下,如果组件需要一些后续的ui更改才能有效,则可能导致ui在半完整状态下进行更新。
选项3将是最有效的,但可能存在一些线程安全问题。
热衷于听取别人的意见。
发布于 2009-10-23 01:30:45
doSomeUi ()有些应该包装在invokeLater ()中,和应该触发任何必要的重绘/重绘-- Swing UI线程将在计算过程中绘制。
在现代VM上,创建大量短期运行的可运行程序的开销很小,不应该成为一个问题。
因此,备选案文2(经建议的修改)应当是它。在编写多线程代码时,慢慢来和正确总是比快速和随机错误好.
发布于 2009-10-23 01:32:10
首先,我会让它运行单线程。作为其中的一个组成部分,我将确保我有好的代码(例如,不扩展Thread和JPanel),并将“业务”逻辑和UI、测试等很好地分离开来。这可能不是什么令人印象深刻的东西,但它是可交付的。把它签到版本控制中。然后也许看看是否有一个小的,热的部分,我可以做平行。
有一些极端的方法来处理多线程问题。在没有共享状态的情况下,我们可以将不可变的操作事件从UI中排出来,并将不可变的更新事件排回队列中,以替换模型的UI副本。或者,我们可以共享状态并非常小心地锁定(我建议可能工作的最大锁--小心回调)。
值得注意的是,您不必为每件小事添加侦听器。您可以使用粗粒度侦听器,然后快速扫描数据结构以获得更新。
需要注意的是,UI发送给“业务”模型的操作和反向状态更新应该尽可能地解耦(即从SwingWorker运行)。
发布于 2012-07-02 02:28:29
重新验证和重新绘制是线程安全的。它们内置了自己的invokeLater,您可以从任何线程和任何时间调用、重新验证和重新绘制。它甚至是如此的聪明,以至于如果您在实际验证任何东西之前调用了一千次重新验证,那么它将把所有的上千次调用合并到一个调用中。
https://stackoverflow.com/questions/1610598
复制相似问题