The above statement is mentioned in the SwingWorker javadoc.
In an application I have seen a lengthy background task runs in a distinct thread and updates the UI as well without a problem (a reference to a Swing component was accessible).
Could it be that something bad can happen?
It's because the Java memory model does not guarantee that memory writes by one thread will be visible to other threads unless you use some form of synchronization. For performance and simplicity, Swing is not synchronized. Therefore, writes from other threads may never be visible to the EDT.
The application you've seen may work most of the time, and it may even work all of the time in some environments. But when it doesn't work, it'll fail in really strange ways that are difficult to reproduce.
All Swing components are implemented to be accessed from a single thread (the event dispatching thread). So there are no protections against concurrent access and concurrent changes of variables and field.
If you are lucky everything works well. But you cannot rely on it and the same code can have massive problems on the next run.
A simple example:
The paint procedure of a JLabel contains the following (simplified) code (taken from BasicLabelUI
class):
# 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);
}
For example if you call setEnabled() from other threads than the EDT it would be possible that you get a label with the enabled icon but the disabled painted text.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With