Water Cooler v2 Water Cooler v2 - 3 months ago 11
Java Question

Do JFrame windows in Swing run on their own separate threads?

I have three questions which are closely related in that they are born out of each other and represent a train of thought, so I am posting them under one question. It would not help me construct the big picture of my question if I posted them separately.

1) Could you please explain in simple language what

SwingUtilities.invokeLater
does? I understand threading, dare I say quite a bit, but still the language of the documentation confuses me. It says:


Causes doRun.run() to be executed asynchronously on the
AWT event dispatching thread. This will happen after all
pending AWT events have been processed. This method should
be used when an application thread needs to update the GUI.
In the following example the
invokeLater
call queues
the
Runnable
object
doHelloWorld

on the event dispatching thread and
then prints a message.


If I put some effort in to make sense of what that says, I think here is what it says, but I couldn't be so sure about it. I think it says:

The
invokeLater
method schedules the main window creation and the setting up of its dispatcher / message pump on the primary thread of the application only and not on a separate thread. It does it by posting the message to create the window and set it up on the main / primary application thread. In other words, the main thread is saying to us, "The window you are asking me to create will be created after I am done doing everything else that is on my plate right now."


But then two things confuses me, which I list as the two questions below.

2) Then why do I need to implement the new window's message loop as a
Runnable
. This implies that I want a separate thread to execute that message loop.

3) I printed out the current thread Id's in the function that creates the window and the function that is the window's message loop, and they are both different threads. So, each window in Swing runs on its own thread? That is insane. Can you please explain to me what is happening here? And also if you could please explain in a paragraph or two the threading model of GUI applications created in Swing?

public static void main(String[] args) {
SwingUtilities.invokeLater(new MainWindowEventLoop());
System.out.println(String.format("Main thread %1$d started.",
Thread.currentThread().getId()));
}

public class MainWindowEventLoop implements Runnable {

@Override
public void run() {
JFrame mainWindow = new MainWindow("Main Window");
System.out.println(String.format("Main window loop running on thread %1$d.",
Thread.currentThread().getId()));
}
}



Output:

Main thread 1 started.

Main window loop running on thread 14.

Answer

It's a little complicated, but Swing is not thread safe. To run the GUI asynchronously and safely, Sun/Oracle uses a locking pattern called Ad-Hoc Thread Confinement. All Swing components must run on the AWT EDT (Event Dispatch Thread) or the result is not thread safe.

Here's a link to Oracle's tutorial. Try to read all of those sections, see if it makes more sense.

https://docs.oracle.com/javase/tutorial/uiswing/concurrency/

Each window does NOT run on its own separate thread. There is only one EDT. Each windows runs on the SAME thread, the EDT. Each Runnable you send to the EDT is executed sequentially, one after the other, when the EDT has the opportunity to do so. Hence the "later" part of invokeLater().

Comments