Swing Toolkit and multithreading - java

It is said that "Swing toolkit is not multithread-Safe?
What is meant by this statement?

Check this link: http://www.jguru.com/faq/view.jsp?EID=131370
So to simplify the implementation of
Swing library they chose it to be not
thread safe. The argument being that
most of the GUI related work happens
in the callbacks from the GUI which
happen on the single GUI thread
anyways. Granted - for long running
tasks the user will have to do more
work if he/she wants to do
multithreaded activity...
Specially the link given for the jfc.
And the this link: http://www.it.uu.se/edu/course/homepage/devgui/vt03/out/ThreadsAndSwing.pdf
After Swing components have been
displayed on the screen, they should
only be operated on by the
event-handling thread. The
event-handling thread (or just event
thread) is started automatically by
the Java VM when an application has a
graphical interface. The event thread
calls methods like paint() on
Component, actionPerformed() on
ActionListener, and all of the other
event-handling methods
ADD
Check the second link I have given, specially the section: The Need for Worker Threads in a GUI Setting (also there is an example for explaining it). Quoting here for reference:
The event thread plays a critical role
in an application with a graphical
interface. Code that will be executed
by the event-handling thread should be
relatively brief and nonblocking. If
the event-handling thread is blocked
in a section of code for a while, no
other events can be processed!

Related

Netbeans GUI and dealing with Threads inside "main"

I'm using Netbeans IDE to make a GUI. The point is that when I add a JFrame frame to my project package:
it declares every variable of the frame (button, textArea, ..etc) as private and can't change it. the problem comes when I'm trying to create thread that uses these variables in run() method inside main method.
note: I've tried to create separate class extends Thread, I can't call it in the main unless I declare it as static, then same problem rises again.
how can I make thread that uses these variables (i.e. appending text to text area) inside the main ?
Do not try to do that. UI elements shall not be accessed from another thread than the Event Dispatch Thread. You will find references on Oracle Java tutorial Concurrency in Swing. Extracts (emphasize mine) :
A Swing programmer deals with the following kinds of threads:
Initial threads, the threads that execute initial application code.
The event dispatch thread, where all event-handling code is executed. Most code that interacts with the Swing framework must also execute on this thread.
Worker threads, also known as background threads, where time-consuming background tasks are executed.
Some Swing component methods are labelled "thread safe" in the API specification; these can be safely invoked from any thread. All other Swing component methods must be invoked from the event dispatch thread. Programs that ignore this rule may function correctly most of the time, but are subject to unpredictable errors that are difficult to reproduce.

Why should I use a separate thread to show a GUI in JAVA

This simple issue confuses me. You can display a JAVA GUI application by setting the frames' setVisible property true. But in almost all the examples I found on internet they use a separate thread to do the same thing.
They do something like this,
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Frame().setvisible(true); //just take the idea of this line
}
});
I found no difference between the two methods. But there must be some special reason, that's why everyone is doing this.
Can someone explain it..thanks!
The main reason for launching your application in this way is that Swing components are not thread-safe so you need to guarantee which thread your GUI will start from: the one called the Event Dispatching Thread (EDT). Without doing this, you can't be sure what thread it will start in, but as noted by several kind commentators, the main thread is guaranteed not to be the EDT.
You should only create, access, or modify UI components from within the EDT. Doing otherwise will result in unexpected behavior (if you're lucky) and/or dirty repaints.
Some resources I suggest you become familiar with:
The Event Dispatch Thread
Painting in AWT and Swing
You could also have a read of Why does my boilerplate Java desktop app JFrame use EventQueue.invokeLater in the main method?
UPDATE
This is the blog I've been trying to find :P
This basically explains why it's important to sync your main with the EDT before getting started, it also describes some of the details about why.
It also describes why many developers make this fundamental mistake when starting their applications (basically, we were told we could, but we never were really allowed to...bad us)
Because every modification you do on the GUI should be done on the event dispatching thread. This is how AWT and SWING are meant to work.
This because the redraw is executed on a single thread, by using invokeLater you let that thread manage it without having potential issued by the lack of thread safety of Swing. Using that syntax you delegate that instructions to be executed on the appopriate thread, which is the one that manages the GUI elements.
Swing is not thread-safe and all components needs to be initialized in the EDT. This will prevent issues such as deadlocking.
The Swing classes are not thread-safe; they get their thread correctness solely from the fact that all actions on them are executed on the same thread (the Event Dispatch Thread, or EDT). So any time you interact with a Swing object, it must be on the EDT -- and SwingUtilities.invokeLater is a good way to do that.
Without that call, if you just called setVisible(true) from any ol' thread, you wouldn't have any thread safety and the Frame might not even see the actions of that method. Worse yet, the Frame could see only some of the actions, breaking internal assumptions and invariants and causing odd behavior, crashes or deadlocks.
Pretty much any operation that invokes Swing methods must be run on the Swing Event Dispatch thread. invokeLater() is the way to ensure that this invariant holds.
Read more about this here.
Also note that the same is true about most other GUI toolkits, such as forms in .NET, MFC and others.
Java gui framework is designed as a single thread to enforce thread safety: this technique is called thread confinement. Any gui operation e.g. components creation, model creation, event sent, etc must therefore execute in the Event Dispatch Thread (EDT).
The way you describe is one way to queue the operation in the EDT.

Java Swing Multiple Event Listeners for a Single Event Source in a single-threaded environment

I am currently learning Swing, and I am new to GUI development in general. In my test application, I have multiple event listners for a single event source, and I am wondering which one of these event listeners will be excecuted first.
Also, I am curious to know how Swing event-handling works in a single-threaded environment, especially when you have multiple listeners for a single event source.
Lastly, I would like to know some common cases where I have to use multiple threads in Swing.
Thanks!
I will try to answer all 3 of your questions. First of all, the order that the ActionListeners fire is not specified. One should never assume a specific order that they will fire. If you need actions to take place in a specific order, put them in the same ActionListener.
When programming Swing, you will 'almost' always be in a multi-threaded environment. There is one thread called the Event Dispatch Thread (EDT). This is the thread that handles all events. Any other processing you do should be done on a different thread, otherwise your Swing GUI can become unresponsive.
A common case for multiple threads in Swing is any time you need to do some processing that takes an extended amount of time. (Intense calculations, IO, database connections) You will want to do the hard work on a separate thread from the EDT. That will keep your GUI responsive.
The Oracle network has a great tutorial on concurrency in Swing. I recommend you check it out.
A Swing programmer deals with the following kinds of threads:
Initial threads, the threads that execute initial application code.
The event dispatch thread, where all event-handling code is executed. Most code that interacts with the Swing framework must also execute on this thread.
Worker threads, also known as background threads, where time-consuming background tasks are executed.
The canonical answer to any multi-threading questions in Swing is to use a SwingWorker. It allows you to easily coordinate background work on a separate thread with the EDT. As usual, Oracle has a great tutorial on how to use SwingWorker.

What is the event dispatching thread?

I know what "thread" means and if I understand the event dispatching thread (EDT) as
"just a thread", it explains a lot but, apparently, it does not explain everything.
I do not understand what is special about this thread. For example I do not understand why we should start a GUI in a the EDT? Why the "main" thread is bed for GUI? Well, if we just do not want to occupy the main thread why we cannot start GUI just in "another thread" why it should be some "special" thread called EDT?
Then I do not understand why we cannot start the EDT like any other thread? Why we should use some special tool (called invokeLater). And why GUI, unlike any other thread, does not start immediately. We should wait until it is ready to accept our job. Is it because EDT can, potentially execute several task simultaneously?
If you decide to answer this question, could you pleas use a really simple terminology because otherwise, I am afraid, I will not be able to understand the answer.
ADDED:
I always thought that we have one "task" per thread. So, in every thread we execute a predefined sequence of commands. But it seems to me that in the event dispatching thread we can have sever task. Well, they are not executed simultaneously (thread switches between different task but there are still several task in one thread). Is it right? For example there is one thread in the EDT which display the main window, and then additionally to that we sent to the EDT another task which should update one of the window components and EDT will execute this new task whenever it is ready. Is EDT differ from other threads in this way?
The event dispatching thread is the thread that handles all GUI events and manages your Swing GUI. It is started somewhere in the Swing code if you have any GUI in your program. The reason it is done behind the scenes is because of simplicity - you do not have to bother with starting and managing an extra thread by yourself.
Regarding the fact that you have to update your GUI with invokeLater() it is because of concurrency issues. The GUI can be modified only from one thread because Swing is not thread safe(it is worth to note that most of toolkits are not thread safe, there is a nice article that gives some ideas why). This is why you have to submit all GUI updates to run on EDT.
You can read more on concurrency in Swing and event dispatching thread in Sun tutorial on concurrency in Swing. Also, if you would like to see how this could be done in a different way you might like to check out SWT toolkit. In SWT you have to manage EDT by yourself.
I always thought that we have one
"task" per thread. So, in every thread
we execute a predefined sequence of
commands. But it seems to me that in
the event dispatching thread we can
have sever task. Well, they are not
executed simultaneously (thread
switches between different task but
there are still several task in one
thread). Is it right? For example
there is one thread in the EDT which
display the main window, and then
additionally to that we sent to the
EDT another task which should update
one of the window components and EDT
will execute this new task whenever it
is ready. Is EDT differ from other
threads in this way?
No, the EDT is not fundamentally different from other threads. And "task" is not a good word to use, because it could be confused with OS-level processes (which are also often called task). Better use Runnable, the interface used to give code to the EDT to execute via invokeLater().
The EDT is basically connected to a queue of things it has to do. When the user clicks a button on the GUI, a Runnable that notifies all listeners attached to the button goes into the queue. When a window is resized, a Runnable doing revalidate&repaint goes into the queue. And when you use invokeLater(), your Runnable goes into the queue.
The EDT simply runs an endless loop that says "take a Runnable from the queue (and if it's empty sleep until you're notified that it's not) and execute it.
Thus, it executes all those little Runnable pieces of code one after another, so that each of them basically has the GUI all to itself while it runs, and doesn't have to worry about synchronizing anything. When you manipulate the GUI from another thread, this assumption is broken, and you can end up with the GUI in a corrupted state.
What is the EDT?
It's a hacky workaround around the great many concurrency issues that the Swing API has ;)
Seriously, a lot of Swing components are not "thread safe" (some famous programmers went as far as calling Swing "thread hostile"). By having a unique thread where all updates are made to this thread-hostile components you're dodging a lot of potential concurrency issues. In addition to that, you're also guaranteed that it shall run the Runnable that you pass through it using invokeLater in a sequential order.
Note that it's not just that you're dodging the concurrency issue: you must respect Sun's guidelines regarding what must and what must not be done on the EDT or you'll have serious problems in your application.
Another benefit is that some Swing components tend to throw unwanted exceptions and when this happen they're automagically dealt with and won't crash the EDT (AFAIK if you really manage to kill the EDT it is automagically restarted).
In other words: you don't have to deal with all the broken Swing components and the exceptions they throw yourself: the EDT is taking care of that (just take a look at the countless Swing bugs throwing exceptions in Sun's bug parade, it's fascinating... And yet most apps keep working normally).
Also, by doing only what's mandatory in the EDT allows the GUI of your app to stay "responsive" even tough there may be tasks running in the background.
The important thing to remember is that Swing classes are not thread-safe. This means that you always should call Swing methods from the same thread, or you risk getting weird or undefined behavior.
So the solution: only call Swing methods from a single thread. This is the EDT thread - it's not special in any way other than that it is the thread designated to call swing methods from.
Now you may ask why are Swing methods not thread safe? After several unsuccessful attempts, GUI toolkit designers discovered that it's inherently impossible to design a thread-safe GUI toolkit. Too often events are passed in opposite directions (input events from bottom to top, application events from top to bottom) which always leads to deadlocks. So that's just the way it is.

Why EventDispatchThread in first place?

This is the design decision I don't understand.
Both Android and JME follow the policy that the thread that started an app is the UI thread and you take care to offload resource-consuming stuff to another threads.
In Swing, on the other hand, you use EventQueue.invokeLater(Runnable) for UI and SwingWorker for background processing.
Now, what's the main thread for?
As mentioned in this Sun article about thread, you can do whatever you want in the main thread, including building a GUI, even though it is risky.
Swing methods are not thread-safe, but as long as no components (Swing or otherwise) have been realized (meaning that the component's paint() method has been or might be called), it was OK until 2004.
Since 2004, as reminded in this SO question, it is mandatory to create the GUI in the EDT.
Back to the question:
Swing has not been implemented with the main thread solely related to GUI because that would force a pure multi-thread approach and:
Component developers do not have to have an in-depth understanding of threads programming: Toolkits in which all components must fully support multithreaded access, can be difficult to extend, particularly for developers who are not expert at threads programming.
Events are dispatched in a predictable order: The runnable objects enqueued by invokeLater() are dispatched from the same event queue as mouse and keyboard events, timer events, and paint requests.
In toolkits where components support multithreaded access, component changes are interleaved with event processing at the whim of the thread scheduler. This makes comprehensive testing difficult or impossible.
Less overhead: Toolkits that attempt to carefully lock critical sections can spend a substantial amount of time and space managing locks.
Whenever the toolkit calls a method that might be implemented in client code (for example, any public or protected method in a public class), the toolkit must save its state and release all locks so that the client code can grab locks if necessary.
When control returns from the method, the toolkit must regrab its locks and restore its state. All applications bear the cost of this, even though most applications do not require concurrent access to the GUI.
So the main thread can be used for initialization (of data and GUI, provided they do not take too much time), while most post-initialization GUI steps naturally occurs in the event-dispatching thread.
Once the GUI is visible, most programs are driven by events such as button actions or mouse clicks, which are always handled in the event-dispatching thread..
The java launcher is not Swing (or AWT) specific. main is a general purpose entry point. AWT will start the Event Dispatch Thread on demand after main has been called, so can't use the main thread. It can even exit the EDT and start a new one.
What's stranger, is that applet lifecycle methods are not called on the AWT EDT.
The main thread is just a thread created to execute the main method.

Categories

Resources