Does SwingUtilities.invokeLater
provides synchronization?
Example:
public class Threads {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
new Threads().test();
}
}).start();
}
List<Integer> list = new ArrayList<>();
void test() {
System.out.println(Thread.currentThread().toString());
for (int i=0; i<10000000; i ) {
list.add(i);
}
SwingUtilities.invokeLater(() -> {
System.out.println(Thread.currentThread().toString());
list.forEach(System.out::println); // list auto synchronized?
});
}
}
Would be list
synchronized when I read values from the list in AWT thread?
CodePudding user response:
Does SwingUtilities.invokeLater provides synchronization?
No. It just runs its parameter later.
Would be list synchronized when I read values from the list in AWT thread?
No, but it doesn't need to be. It is sent to invokeLater
after it was created and assigned with values. It doesn't change at any later time so it won't be changed while the code sent to invokeLater
is executed.
CodePudding user response:
To summarize some facts:
- in general Swing is not threadsafe
- everything GUI-related runs on the awt Event Dispatching Thread
- EDT does not guarantee the order of execution
- EDT dispatches time-consuming work to worker threads (> worker pattern)
- EDT should execute only small GUI-related tasks otherwise UI will freeze
SwingUtilities.invokeLater
is based onawt.EventQueue.invokeLater
So if you have SwingUtilities.invokeLater
and give it a Runnable (your function), this Runnable will be put into an event-queue for the dispachter thread (EDT) which will execute your Runnable asynchronously.
To be exact:
Yes, your code as part of invokeLater
will run in parallel (if that is what you meant) on the EDT which runs asychronously to the main thread.
No, it is not synchronized in matter of "another thread entering it" because it is designated only to be executed by the EDT.
Although it is not part of the question: EDT should not be misused in that way. Instead you should put this task into a worker thread and let EDT be for what it has been created: dispatching GUI related tasks to worker threads.