I have an app with a main object (containing Swing GUI) and a supporting thread which calls on the handle() method of the object.
I noticed that when the handle() method is synchronized, while the thread is using the handle() method, the GUI on the main object are unresponsive. Code:
public synchronized void handle()){
//method code
}
i remove the synchronized keyword from handle(), the GUI is responsive even when the thread is using the handle() method.
An interesting thing to note is that when I used another object as a lock, the GUI becomes responsive again when the thread is using the handle() method. Code:
public void handle(){
synchronized(anotherObj){
//method code
}
}
This suggests that Swing GUI uses methods that are synchronized. Am I right? Feel free to point me to any resources - couldn't quite find what I wanted.
Thanks.
What is your "handle" method and what does it do? I believe that Swing does not use synchronization for the most part and its documentation in fact states in its API that it is not thread-safe (e.g., have a look here). Instead it uses a single thread for user interactions and program painting, the EDT or Event Dispatch Thread, and all programs that interact with Swing must respect this single thread model by calling most all Swing calls on the EDT. I suspect this is where your problem lies.
For more on Swing threading and use of background threads, please have a look here: Concurrency in Swing
Edit 1
(From my comment) I have to ask also, why this method is synchronized? Since we queue all Swing calls onto the event queue, this probably isn't necessary and is possibly harmful. A Swing program freeze almost always is due to a concurrency issue so this discussion is relevant.
You might want to make a small compilable test program (an SSCCE) that demonstrates your problem (the GUI freeze) and post it here so we can test it for ourselves.
Related
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.
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'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/
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
Please tell me what does the above code does actually. I am looking for line by line explanation. especially the first line and tell me why do we use that and in what scenarios we have to use this.
In this Example you see an anyonmous class that derives from Runnable. This anonymous class overrides the run method of the interface runnable. Then this anonymous class is instantiated and passed to the EventQueue.invokeLater method, which is a static method. This method appends the object into... well... the eventQueue. In the EvenQueue are many events, like keyboard events or mouse events or whatever. There is a Thread that continuesly polls data from this queue. Once that Thread reaches the anonymous class that was instantiated here, it will execute the run() method, which will instantiate an Object of class NewJFrame and set it to be visible.
The whole point of doing this this complicated is that the new JFrame().setVisible(true) part is not executed in the main thread, but in the event dispatching thread. In Swing you must execute all code that modifies the user interface in the event dispatching thread.
Single-Thread-Model and EDT
Most modern UI libraries adopt the single-thread-model. That means, all the manipulation upon UI components MUST be done on the same single thread. Why? That's because allowing UI components being updated from multiple threads will lead to chaos since most Swing object methods are not "thread safe". For simplicity, efficiency and robustness, single-thread-model is adopted.
In Swing, the very thread that serve the single-thread-model is called the Event Dispatching Thread, i.e. EDT. It is not provided by Swing. It is provided by Abstract Window Toolkit, i.e. AWT.
Worker thread vs UI thread
A non-trivial GUI application usually has many threads. In modern GUI application, there can be many worker threads to do dirty work, but there's only one UI thread (Swing calls it EDT) to update the GUI. Worker threads usually need to reflect their work progress in GUI, so they need to communicate with the UI thread about that. So how does this communication happen?
java.awt.EventQueue
The communication happens through a message queue model. The java.awt.EventQueue is the very class that provides a event queue globally. This global event queue serves as the communication channel to the EDT. EDT picks up messages from this EventQueue and update UI components accordingly. If some other part of your program wants to manipulate the UI, that part of code should call EventQueue.invokeLater() or EventQueue.invokeAndWait() to queue a message into EventQueue. EDT will process all the pending messages in the EventQueue and eventually get to the message.
the main thread
Your code snippet usually resides in the main() thread, the main thread can be viewed as some kind of a worker thread here. Only that instead of updating the GUI by posting messages to EventQueue, it initiates the GUI. Anyway, initiation can be viewed as a kind of work, too.
After the GUI is initiated, the main thread will exits and the EDT will prevent the process from exiting.
And another good explanation:
Java Event-Dispatching Thread explanation
An interesting article:
Multi-threaded toolkit, a failed dream?
This is a block of code that is instructed to execute at a later time (sometimes called a deferred). The inner class (new Runnable() {...}) is essentially allowing you to pass a block of code that will be run. The invokeLater method guarantees that the block of code will be run, but makes no guarantees of when. Sometimes it's not safe to have certain code run immediately, and its too verbose to do the multi-threading yourself. So Java provides this utility method to safely run the code. The code will be run very soon, but not until it's safe to do so.
The invokeLater call will put the specified runnable on a queue to be processed later. That is, the code inside the run() method will not have been run yet when the invokeLater method call returns.
There are two typical use-cases for this type of code.
The currently executing code is run in a background thread. Background threads cannot access most of the swing API. Read more here for the reason for this. If the current thread is already the UI thread there is no reason and the call can safely be removed.
The current block must be exited, ie the code reach the last brace. This may cause resources to be released and so on. This is not so common.
An anonymous class is passed as parameter to the invokeLater call. It is the same as this code.
private void foo()
{
java.awt.EventQueue.invokeLater(new JFrameCreator());
}
private class JFrameCreator implements Runnable
{
public void run() {
new NewJFrame().setVisible(true);
}
}
Source
The invokeLater() method takes a Runnable object as its parameter. It sends that object to the event-dispatching thread, which executes the run() method. This is why it's always safe for the run() method to execute Swing code.
-IvarD