Java - 使用Thread而不是SwingWorker

jav*_*ava 0 java swing multithreading thread-safety swingworker

我无法真正获得使用swingworker的优势,而不仅仅是将繁重的任务放在一个(简单的)后台线程中.

这只是一个codesnippet,但显示了计算整数并将值放在JLabel中的任务.(这是在ActionPerformed中)

Thread t = new Thread() {
    public void run() {
        for (int i = 0; i < 2000000; i++) {
            counter++;
            label.setText(Integer.toString(counter));       
        }
    }
};

t.start();
Run Code Online (Sandbox Code Playgroud)

我被告知使用抽象的SwingWorker类并覆盖doInBackground,processdone等方法,而不是这个简单的代码片段.

只需使用Thread更新标签,它就可以正常工作.为什么要创建一个扩展swingworker并实现抽象方法的新类?我现在只能把Swing-worker视为线程安全,那是答案吗?

Mad*_*mer 8

Swing不是线程安全的,在EDT上下文之外修改UI,就像你愿意的那样,导致随机的绘制工件和脏的绘制问题几乎无法追踪.

有关更多详细信息,请参阅Swing中的并发

将更新推送到队列的publish方法,该SwingWorker队列在EDT内处理并推送到该process方法. done也可以在EDT的上下文中调用,从而可以安全地更新UI

现在,您可以使用类似......

Thread t = new Thread() {
    public void run() {
        int counter = 0 ;
        for (int i = 0; i < 2000000; i++) {
            counter++;
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    label.setText(Integer.toString(counter));
                }
            });
        }
    }
};

t.start();
Run Code Online (Sandbox Code Playgroud)

在Java 8+下你可能不会遇到很多问题,但是Java 6对于需要final匿名类的变量非常挑剔,这就是为什么我通常会避免它.

SwingWoker通过它的setProgress方法也有进步支持PropertyChangeListener,这也是你可以提供反馈的另一种方式......