SwingWorker javadoc中提到了上述语句。
在一个应用程序中,我看到一个冗长的后台任务在一个不同的线程中运行并且更新UI也没有问题(可以访问对Swing组件的引用)。
可能会发生不好的事情吗?
答案 0 :(得分:6)
这是因为Java memory model不保证一个线程的内存写入对其他线程可见,除非您使用某种形式的同步。为了性能和简单性,Swing不同步。因此,其他线程的写入可能永远不会被EDT看到。
您看过的应用程序大部分时间都可以正常运行,甚至可能在某些环境中一直运行。但是当它不起作用时,它会以一种难以复制的奇怪方式失败。
答案 1 :(得分:5)
实现所有Swing组件以从单个线程(事件调度线程)访问。因此,对变量和字段的并发访问和并发更改没有任何保护。
如果你很幸运,一切都很顺利。但是你不能依赖它,同样的代码在下次运行时可能会遇到大量问题。
一个简单的例子:
JLabel的绘制过程包含以下(简化)代码(取自BasicLabelUI
类):
# assume your label is enabled
Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon();
# what happens if another thread calls label.setEnabled(false) at this point?
if (icon != null) {
icon.paintIcon(c, g, paintIconR.x, paintIconR.y);
}
if (label.isEnabled()) {
paintEnabledText(label, g, clippedText, textX, textY);
}
else {
paintDisabledText(label, g, clippedText, textX, textY);
}
例如,如果从EDT之外的其他线程调用setEnabled(),则可能会获得带有启用图标但禁用的绘制文本的标签。