Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have finished a GUI app. I have four classes: Main, UserWindow, Task1, Task2. Main class contains a boolean variable buttonStartPressed. Main method starts an instance of the UserWindow class, and waits until the user presses the Start button. As user presses the Start button ( in the UserWindow) the ActionListener assigns true to the static boolean buttonStartPressed and the Main method continues.
Main.java
public static void ......
static boolean buttonStartPressed = false;
...........
while (!buttonStartPress) {
Thread.sleep(50);
}
Task1 t1 = new Task1();
.....
}
}
It works fine, however I do not like the while loop. I feel that this is not the conventional way to write an application. There is another way: i could combine Main and UserWindow classes, and the result of the ActionListener (buttonPressed) would be the start of the Task1. But, on the other hand, I think that Main class and UserWindow classes should be separate from each other.
Yeah, that's wrong. You shouldn't have busy loops....anywhere.
Do you even need the buttonStartPressed variable? Why would you be interested in knowing if it has been pressed, isn't the main idea to perform some action when the button is pressed?
You should create the Task1 in your actionPerformed() method, and depending on what you're trying to do, start a thread that'll perform the task (or just run it in the EDT if it's really fast to do, so it won't freeze the GUI).
Swing (and almost every GUI toolkit) has a dedicated thread. This thread, the Event Dispatch Thread, is started when you first need it. This is generally when you setVisible a JFrame. This thread is a giant loop, whose role is to consume input events and repaint events and to run some logic accordingly.
In your case, you actually have two threads. The first is the main thread and the second is the EDT. Your main thread is doing a busy wait. The code of your actionListener is executed in the EDT as soon as the user presses the button.
You are using a boolean variable as a way to make your two threads communicate. Using some shared memory is indeed one possible way of doing inter-thread communication.
Now, as you suspected you should avoid doing busy waits. It uselessly consumes CPU time, it disturbs the other threads each time it wakes up, and it has an inevitable reaction delay.
Communicating using shared memory is generally bad, too. It is a too low-level way of communicating, and it is often done wrong. Access to a piece of data from two threads must be protected by a locking mechanism. Even a data as simple as a boolean can bite you, as there is no guarantee that if one thread writes to it, the other one will see the modification. In your example, the boolean should be at least declared volatile to have this guarantee.
So, adding the volatile keyword, your solution works : you have an EDT who is happily doing its stuff, and when the user clicks the button, the main thread executes Task1. The first question to ask yourself is : is Task1 a time-consuming task ? Indeed, the simplest solution would be to run Task1 in the EDT, by calling it from actionListener. Be warned that executing some code in the EDT freezes the GUI. If Task1 lasts for less than 100ms, the user won't even notice the freeze, and there is no point in executing it in another thread. If you are worried about coupling your GUI class with your "task" class, then you should just use the observer pattern to prevent a direct dependency.
If the task is time-consuming and you don't want your GUI to freeze, then you should use multiple threads. One solution is the one you implemented. It is somewhat limited, because you only have one main thread, but it works. Your problem now is to make those threads communicate. A really common pattern in inter-thread communication is to use a blocking queue. This is also a shared piece of data, but it is designed to be used by multiple threads. One thread (EDT) writes to it (add()), and the other reads from it (take()) and blocks until something has been written. This may seem overkill for your simple example, but it is a very convenient way of sharing data between threads. The objects written to the blocking queue can be anything ; for example they can represent commands to execute.
A more conventional way of executing a time-consuming function from the GUI is to create or use a dedicated thread when you need to. This can be done using low-level APIs (Thread) or using higher level ones (ExecutorService), both being quite easy to use. Again, use the observer pattern if you want to decouple the GUI action from the thread creation.
I apologize if this wall of text does not offer a simple answer to your question, but there are many things to consider when we mix GUI and threads. I hope it will be useful for you, to understand what your other options are.
Related
Suppose I have a nametag, which is UI component in GUI program.
The nametag will constantly change its text based on the data.
If the user change his/her name data, then he/she will see the change in nametag.
For this task, my code looks like this:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
String name = data.getName();
nametag.setText(name);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Since the reaction time of 0.1s seems instant to people, I included Thread.sleep(100) for computer to take a break.
However, I am not sure if that helps the computer in terms of energy usage or something. Is sleep method in this case complete waste of time? No benefit at all?
Thread.Sleep has been used for many things it shouldn’t be used for.
Here’s a list of the common mistakes:
The thread needs to wait for another thread to complete
In this case no value, other than infinite, passed to Thread.Sleep will be correct. You simply don’t know when the other thread will complete using this method. If the thread completed after Sleep returned you’ll likely have synchronization problems. If the other thread completed before Sleep returned the thread was needlessly blocked for an amount of time rendering the benefits of multithreading limited or moot. In the control circumstances where you’ve tested this it may seem like it always works; it just takes a busy program to cause it to faile: a defrag program, a sudden influx of network traffic, a network hiccup, etc.
The thread needs perform logic every n milliseconds
As noted earlier, Sleep means relinquish control. When your thread gets control again isn’t up to the thread; so it can’t be used for periodic logic.
We don’t know why Thread.Sleep is required; but if we take it out the application stops working
This is flawed logic because the application still doesn’t work with Thread.Sleep. This is really just spackling over the problem on that particular computer. The original problem is likely a timing/synchronization issue, ignoring it by hiding it with Thread.Sleep is only going to delay the problem and make it occur in random, hard to reproduce ways.
Source: http://blogs.msmvps.com/peterritchie/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program/
This doesn't answer your direct question, but it does help address an XY Problem component of your question:
It looks like you're listening for object state changes by polling: by constantly testing an object to see what its state is and whether it's changed, and this is a bad idea, especially when coding for an event-driven GUI. Much better to use an observer pattern and be notified of state changes when or if they occur. That is how the Swing GUI library itself was written, and you should strongly consider emulating this.
Some ways to be notified of changes are to use component event listeners which can listen for changes to Swing components, such as ActionListeners, ChangeListeners, ItemListeners, and the like. Another way when listening to non Swing component items is to use SwingPropertyChangeSupport and PropertyChangeListeners and in this way to create "bound" properties of your class. This is often used for non-GUI model classes.
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 have read a number of articles on the internet about when something should run in the EDT, and when it shouldn't. But I'm still not sure I understand, so I'd like to ask a few question about this:
What pieces of code are going to run by default inside the EDT?
What pieces of code are going to be run be default outside the
EDT?
When should I use InvokeLater() so something that by default would
run outside the EDT, will run inside it?
When should I prevent a piece of code from running (by default) inside the EDT, by creating a new thread and putting that code inside it?
Thanks
All the code executed by an event listener.
The code in your main method, the code executed inside a thread that you explicitely started, or that has been started by the usage of a Timer or SwingWorker.
When creating a Swing GUI in your main method. Or when you want to interact with a Swing component (or its model) from inside a background thread.
When this piece of code is blocking (like long IO) or is taking more than a few milliseconds to execute. All the code executed from inside the EDT prevent this thread from doing its main job: repainting the GUI and reacting to events.
First of all thank you so much for editing and formatting your question very well. It helps a lot when answering your question.
Also i have to admit i am not 100% sure about my answers, so guys: feel free to correct me if i am wrong.
Everything which changes your graphical user interface.
Not quite sure about that.
If you need to update your gui with the time intensive calculations.
For example if you want to show the numbers from 0to 100000000 in a
JLabel.
Everything which would block your gui from user interaction because
it takes a lot of time, for example some calculations with a lot
of datasets.. But you need to make sure to access values only from
one thread or to synchronize the threads with volatile and
synchronize...
In my Java application with a Swing GUI, I would like to achieve the following.
There is a non-GUI thread running, performing some work. At one point, this thread needs input from the user before it can continue. Then, I would like to make some changes to the GUI, await a specific GUI action (like the user pressing the OK button), get the entered data from the GUI to the non-GUI thread, and let it continue with the computation.
Looking around, I have found a lot of information about how to initiate the execution of a (long running) task from the Swing GUI thread on another thread, but nothing on my problem.
SwingUtilites.invokeAndWait sounds like it does the job, but first, it takes a Runnable argument instead of a Callable, so there is no straightforward way to return a result, and second, it does not solve the problem of waiting for a certain GUI event.
I realize I could make up my own solution using e.g. a CountDownLatch, but to me, the problem seems frequent enough for there to be a standard solution.
So, my questions are: Is this really a frequent problem, and if yes, is there a solution in the standard library / libraries? If there is no standard solution, how would you solve it? If this problem doesn't occur often, why not?
Kicking off the GUI changes is easy, so I assume you're only asking about getting data back to the worker thread.
First, create a Blocking Queue. Have the worker thread call take() on the queue, and it will block. In GUI space, once the user enters valid input, put it on the queue with offer() and the worker thread will receive the data and can continue.
I think, you can use ExecutorService where you can also track progress of your task through Future interface.
java.awt.EventQueue.invokeLater works nicely for running code on the AWT EDT. Propbably best to copy mutable data or better use immutable data. Locks are possible, but a bit dicey.
If you other thread is an event dispatch loop, you could implement something like invokeLater for your thread (but don't make it static!). Probably use it behind some interface that makes sense to the behaviour of the thread - so it's real operations rather than run which is specified as doing anything it pleases. If your thread is going to block, then a BlockQueue is fine, but don't block from the AWT EDT.
java.awt.EventQueue.invokeAndWait is like using a lock. Probably you are going to use another lock. Or perhaps a lock like invokeAndWait on you own thread. If you don't, AWT uses a lock anyway. So, uncontrolled nested locks, that probably means deadlock. Don't use invokeAndWait!
final bool result = doSomething();
SwingUtilities.invokeLater( new Runnable(){
//Runnable method implementation.
//use result in your method like local var.
});
Make sure that your shared data is synchronized use lock objects.
If you need to pass arguments to Runnable just make your local variables final,
and use them in run method.
I am trying to implement a GUI in java but I am beginner in swing. I want to make something clear. I read that in order to keep the GUI responsive I should use the SwingWorker class to do the task in a separate thread. Ok so far.
No I have a model with around 15 methods that are remote methods. Each method returns different object type as a result than the others.
In my view the user presses a button and the appropriate method in the model is called. Without using the swingworker the GUI froze. My question is, am I supposed to create 15 subclasses of Swingworker threads and create a NEW instance of each as needed according to user's actions? Is my understanding correct? Is there a standard way for this or what I say is a correct approach?
Thanks!
Have a look at this: Simple Background Tasks.
It seems you have two concerns. Firstly, regarding the amount of code required when using SwingWorker: you do need to create a subclass of SwingWorker for each action, but that doesn't mean they need to be top-level, named classes, or in their own files. They can be anonymous classes, as shown in the article, so that the code is within your GUI's event-handling code.
Secondly, regarding instantiation of SwingWorker objects: you can't reuse a SwingWorker, but since the jobs are being executed as a result of user activity (e.g. clicking a button), you shouldn't encounter any performance problems with instantiating new objects each time.
By all means, SwingWorkers get the job done. In my experience, I haven't liked using the SwingWorkers for just one little job. I prefer to spawn off a thread, and have that thread ask the EventDispatch thread to update the GUI. Only the EventDispatch thread should update the UI, though there are a few exceptions.
I would suggest reading about threads in threads in Swing.
Though threading can get heavy, and maybe this solution would not work for you in all cases, if a seperate thread needs to spark a change in GUI, use something like,
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run()
{
// this codes runs on the event dispatch thread
// update the ui here.
}
});