I'm reading Java Threads 3rd Ed. by Oaks and Wong (O'Reilly 2004).
They carry an example of a Swing typing game throughout the book.
The classes they define are mostly custom subclasses of javax.swing.JComponent.
What seems quite wrong to me is that they make those JComponents thread safe with various synchronization methods. I was under the impression that Swing components should not be thread safe, but rather that they should always be accessed from the Swing event dispatching thread. (Amusingly, one of the few times where they modify a component through the Swing EDT, it's for a setText, which is one of the very few Swing methods that do not need to be called from the EDT.)
I would like to know from some of you who have a lot of experience writing/reading Swing code:
Is it common for programmers to make Swing components synchronized instead of always modifying them through the EDT? Is it tolerable?
EDIT:
I noticed it is nearly the same question as this thread. However it does not say what programmers actually do in the wild. I'm puzzled that an O'Reilly book would so blatantly violate the Swing threading model.
EDIT:
I discovered that they do briefly explain somewhere in the middle of the book the Swing threading model. Nonetheless I'd like to have an answer to my question. I have the feeling most who read this book will end up violating the Swing threading model since most of their examples do.
EDIT:
If you want to look at the code, you can Download examples code as a zip file. See for example ch03/example1/AnimatedCharacterDisplayCanvas.
EDIT:
I just learned that setText will not be thread-safe in Java7 (release in July 2011).
Trivially, as long as the synchronized methods do not execute on the EventQueue, they won't block the event dispatch thread. Conversely, a method executing on another thread should always use the EventQueue to dispatch code via invokeLater(), invokeAndWait(), or a related mechanism such as javax.swing.Timer or javax.swing.SwingWorker. As a practical matter, these are reliable. The examples may be correct, but they should be examined from this perspective.
The EventQueue API says, "The only requirements are that
events...are dispatched...in the same order as they are enqueued." In my opinion, this is tantamount to the "happens-before" relation of java.util.concurrent
and the JLS. A more detailed discussion may be found here.
You should never have synchronized blocks on Swing components, its going to cause weird problems when its trying to be rendered.
Swing is not thread safe because everything is supposed to be updated on the EDT, even creation of Swing components.
Long running processes should be moved to a background thread or a SwingWorker. When a thread other than the EDT needs to make components or make updates to a component it should be wrapped using SwingUtilities.invokeLater()
"Swing components are not inherently thread safe, and as a general rule, after Swing components have been made visible on the screen, you can only safely modify their data from the event thread. If you modify Swing component data from any thread other than the event dispatching thread, you must take precautions to ensure data integrity. An exception to this rule is the setText method on a JTextComponent or any of its subclasses, or any Swing component method whose documentation explicitly states it is thread safe."
Monica Pawlan
http://java.sun.com/developer/technicalArticles/Threads/swing/
Related
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.
I've recently started learning and exploring the basics of GUI programming in Java.
Having been programming for a while I have only done backend work or work and as a result the closest I've gotten to user interfaces is the command console (embarrassing I know).
I'm using Swing and as far as I can gather that means by extension I am also using AWT.
My question is based on this piece of code:
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new frame.setVisible(true);
}
} );
I have been researching this for a while as I wanted to fully understand this strange piece of code and have come across the term 'Event-Dispatching Thread' multiple times. Correct me if I'm wrong but as I understand it; it has to do with using multiple threads and how Java Swing interprets those threads. I gather as well that the above code is used to make sure all the threads are 'safe' before it creates the window, hence the invokeLater?
I have read that:
"You can only call methods that operate on the frame from the Event-Dispatching Thread"
and that only under certain circumstances can you call methods that operate on the frame from the main method.
Can somebody please clarify to me what exactly the Event-Dispatching Thread is?
How it relates to multiple threads of execution and how those threads are not safe to be called from the main method? Also why do we need this invokeLater?
Can we not just create the window as any other object?
I've hit a bit of a road block in my research as I'm not grasping these relations and ideas.
A side note is that I like to base my knowledge on in-depth understanding as I believe this leads to the best overall outcome and as a result the best programs. If I understand in-depth how something works then you can use the tips and tweaks effectively rather than just parroting them back in to code, so please don't be afraid to give me some extra in-depth explanations and broaden my knowledge.
Thank you.
The event dispatch thread is a special thread that is managed by AWT. Basically, it is a thread that runs in an infinite loop, processing events.
The java.awt.EventQueue.invokeLater and javax.swing.SwingUtilities.invokeLater methods are a way to provide code that will run on the event queue. Writing a UI framework that is safe in a multithreading environment is very difficult so the AWT authors decided that they would only allow operations on GUI objects to occur on a single special thread. All event handlers will execute on this thread and all code that modifies the GUI should also operate on this thread.
Now AWT does not usually check that you are not issuing GUI commands from another thread (The WPF framework for C# does do this), meaning it's possible to write a lot of code and be pretty much agnostic to this and not run into any problems. But this can lead to undefined behavior, so the best thing to do, is to always ensure that GUI code runs on the event dispatch thread. invokeLater provides a mechanism to do this.
A classic example is that you need to run a long running operation like downloading a file. So you launch a thread to perform this action then, when it is completed, you use invokeLater to update the UI. If you didn't use invokeLater and instead you just updated the UI directly, you might have a race condition and undefined behavior could occur.
Wikipedia has more information
Also, if you are curious why the AWT authors don't just make the toolkit multithreaded, here is a good article.
EventDispatchThread (EDT) is special thread reserved only for Swing GUI and *Swing's related events e.g. create/change/update Swing JComponents, more for asked questions here and here
all output to the GUI from BackGround Tasks, Runnable#Thread must be wrapped into invokeLater(), from synchronized Objects into invokeAndWait();
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.
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.
I've often heard criticism of the lack of thread safety in the Swing libraries. Yet, I am not sure as to what I would be doing in my own code with could cause issues:
In what situations does the fact Swing is not thread safe come into play ?
What should I actively avoid doing ?
Never do long running tasks in response to a button, event, etc as these are on the event thread. If you block the event thread, the ENTIRE GUI will be completely unresponsive resulting in REALLY pissed off users. This is why Swing seems slow and crusty.
Use Threads, Executors, and SwingWorker to run tasks NOT ON THE EDT ( event dispatch thread).
Do not update or create widgets outside of the EDT. Just about the only call you can do outside of the EDT is Component.repaint(). Use SwingUtilitis.invokeLater to ensure certain code executes on the EDT.
Use EDT Debug Techniques and a smart look and feel (like Substance, which checks for EDT violation)
If you follow these rules, Swing can make some very attractive and RESPONSIVE GUIs
An example of some REALLY awesome Swing UI work: Palantir Technologies. Note: I DO NOT work for them, just an example of awesome swing. Shame no public demo... Their blog is good too, sparse, but good
This is one of those questions that makes me glad I purchased Robinson & Vorobiev's book on Swing.
Anything that accesses the state of a java.awt.Component should be run inside the EDT, with three exceptions: anything specifically documented as thread-safe, such as repaint(), revalidate(), and invalidate(); any Component in a UI that has not yet been realized; and any Component in an Applet before that Applet's start() has been called.
Methods specially made thread-safe are so uncommon that it's often sufficient to simply remember the ones that are; you can also usually get away with assuming there are no such methods (it's perfectly safe to wrap a repaint call in a SwingWorker, for example).
Realized means that the Component is either a top-level container (like JFrame) on which any of setVisible(true), show(), or pack() has been called, or it has been added to a realized Component. This means it's perfectly fine to build your UI in the main() method, as many tutorial examples do, since they don't call setVisible(true) on the top-level container until every Component has been added to it, fonts and borders configured, etc.
For similar reasons, it's perfectly safe to build your applet UI in its init() method, and then call start() after it's all built.
Wrapping subsequent Component changes in Runnables to send to invokeLater() becomes easy to get right after doing it only a few times. The one thing I find annoying is reading the state of a Component (say, someTextField.getText()) from another thread. Technically, this has to be wrapped in invokeLater(), too; in practice, it can make the code ugly fast, and I often don't bother, or I'm careful to grab that information at initial event handling time (typically the right time to do it in most cases anyway).
It's not just that Swing is not thread-safe (not much is), but it's thread-hostile. If you start doing Swing stuff on a single thread (other than the EDT), then when in cases where Swing switches to the EDT (not documented) there may well be thread-safety issues. Even Swing text which aims to be thread-safe, isn't usefully thread-safe (for instance, to append to a document you first need to find the length, which might change before the insert).
So, do all Swing manipulations on the EDT. Note the EDT is not the thread the main is called on, so start your (simple) Swing applications like this boilerplate:
class MyApp {
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
runEDT();
}});
}
private static void runEDT() {
assert java.awt.EventQueue.isDispatchThread();
...
An alternative to using intelligent skins like substance is to create the following utility method:
public final static void checkOnEventDispatchThread() {
if (!SwingUtilities.isEventDispatchThread()) {
throw new RuntimeException("This method can only be run on the EDT");
}
}
Call it in every method you write that is required to be on the event dispatch thread. An advantage of this would be to disable and enable system wide checks very quickly, eg possibly removing this in production.
Note intelligent skins can of course provide additional coverage as well as just this.
Actively avoid doing any Swing work at all except on the event dispatching thread. Swing was written to be easy to extend and Sun decided a single-threaded model was better for this.
I have had no issues whilst following my advice above. There are some circumstances where you can 'swing' from other threads but I've never found the need.
If you're using Java 6 then SwingWorker is definately the easiest way to deal with this.
Basically you want to make sure that anything that changes a UI is performed on the EventDispatchThread.
This can be found by using the SwingUtilities.isEventDispatchThread() method to tell you if you are in it (generally not a good idea - you should know what thread is active).
If you aren't on the EDT then you use SwingUtilities.invokeLater() and SwingUtilities.invokeAndWait() to invoke a Runnable on the EDT.
If you update UI's not on the EDT you get some incredibly strange behaviour. Personally I don't consider this a flaw of Swing, you get some nice efficiency by not having to synchronize all of the threads to provide a UI update - you just need to remember that caveat.
The phrase 'thread-unsafe' sounds like there is something inherently bad (you know... 'safe' - good; 'unsafe' - bad). The reality is that thread safety comes at a cost - threadsafe objects are often way more complex to implement (and Swing is complex enough even as it is.)
Also, thread-safety is achieved either using locking (slow) or compare-and-swap (complex) strategies. Given that the GUI interfaces with humans, which tend to be unpredictable and difficult to synchronize, many toolkits have decided to channel all events through a single event pump. This is true for Windows, Swing, SWT, GTK and probably others. Actually I don't know a single GUI toolkit which is truly thread-safe (meaning that you can manipulate its objects' internal state from any thread).
What is usually done instead is that the GUIs provide a way to cope with the thread-unsafety. As others noted, Swing has always provided the somewhat simplistic SwingUtilities.invokeLater(). Java 6 includes the excellent SwingWorker (available for previous versions from Swinglabs.org). There are also third party libraries like Foxtrot for managing threads in Swing context.
The notoriety of Swing is because the designers have taken light handed approach of assuming that the developer will do the right thing and not stall the EDT or modify components from outside the EDT. They have stated their threading policy loud and clear and it's up to the developers to follow it.
It's trivial to make each swing API to post a job to the EDT for each property-set, invalidate, etc., which would make it threadsafe, but at the cost of massive slowdowns. You can even do it yourself using AOP. For comparison, SWT throws exceptions when a component is accessed from a wrong thread.
Here's a pattern for makng swing thread-freindly.
Sublass Action (MyAction) and make it's doAction threaded.
Make the constructor take a String NAME.
Give it an abstract actionImpl() method.
Let it look like.. (pseudocode warning!)
doAction(){
new Thread(){
public void run(){
//kick off thread to do actionImpl().
actionImpl();
MyAction.this.interrupt();
}.start(); // use a worker pool if you care about garbage.
try {
sleep(300);
Go to a busy cursor
sleep(600);
Show a busy dialog(Name) // name comes in handy here
} catch( interrupted exception){
show normal cursor
}
You can record the time taken for the task, and next time, your dialog can show a decent estimate.
If you want to be really nice, do the sleeping in another worker thread too.
Note that not even the model interfaces are thread safe. The size and the content are queried with separate get methods and so there is no way of synchronizing those.
Updating the state of the model from another thread allows for it to at least paint a situation where size is still bigger (table row is still in place), but the content is no longer there.
Updating state of the model always in EDT avoids these.
invokeLater() and invokeAndWait() really MUST be used when you are doing any interaction with GUI components from any thread that is NOT the EDT.
It may work during development, but like most concurrent bugs, you'll start to see weird exceptions come up that seem completely unrelated, and occur non-deterministly - usually spotted AFTER you've shipped by real users. Not good.
Also, you've got no confidence that your app will continue to work on future CPUs with more and more cores - which are more prone to encountering weird threading issues due to them being truely concurrent rather than just simulated by the OS.
Yes, it gets ugly wrapping every method call back into the EDT in a Runnable instance, but that's Java for you. Until we get closures, you just have to live with it.
For more details about threading, Taming Java Threads by Allen Holub is an older book but a great read.
Holub, really promotes responsive UI and details examples and how to alleviate problems.
http://www.amazon.com/Taming-Java-Threads-Allen-Holub/dp/1893115100
http://www.holub.com/software/taming.java.threads.html
Love the "If i was king" section in the end there.