I am not clear about thread confinement.
In swing all the gui components must be updated through the EDT. SwingWorker is provided in Java6 for lengthy operations, and in the done method the gui components can be updated. My understanding was that the gui components in the done() method are updated in the EDT. Therefore there should be no synchronization problems. But here link text
it says:
Because the ImageRetriever class will
download an image and place it on a
large label, providing the label and
image URL in the constructor is
convenient. ImageRetriever needs the
URL to retrieve an image. Provide the
label so that the ImageRetriever
instance can set the label’s icon
itself. If you use inner classes, you
might not even provide this
information in the constructor,
because the worker thread will be able
to access the information directly.
However, providing the information in
the constructor helps your application
to be more thread-safe because that
information will not be shared among
ImageRetriever instances
I am confused on this. If the SwingWorker methods update the gui components (in the example of the link the JLabel) in the EDT, why is it more thread-safe to not share them among ImageRetriever(=SwingWorker) instances? If we have multiple SwingWorkers and in the done() method they update the same component, we must use synchronization primitives for the update? Am I missunderstanding something? Doesn’t thread-confinement mean that only 1 thread will do all the actions? Aren’t swingworkers thread-confined?
Thanks
If the label is declared in the parent class and for some reason a new value is assigned to that variable at some point, then all the swingworkers will see the update. Because this might happen while the EDT is updating things, it can lead to weird behaviors.
For instance:
If the label variable is shared you will get an inconsistent state (label without text or icon).
Update
Storing the label as a variable passed through the constructors is a way to avoid this issue. If you want to see changes but not in the middle of a method execution, on way is to use a method local variable. You assign it at the beginning of the method to make sure it’s not going to be changed outside.
If you use inner classes and the attribute of the parent class this will look like this:
If the variable is defined as an attribute of the SW, you will have to create some way of getting the value stored in the main class (eg. a getter)