After having some trouble with setting up a thread to start my MIDI sequencer I decided to simply remove it, although it would slow my UI down I would be able to use it correctly.
What I noticed however was that even when playing the Sequencer the UI was very much active, even if it was playing around 500 notes the UI worked perfectly fine.
Now I know that in C# if you are doing something intensive it is advisable to load it on a new Thread as it will free the UI. Is it the same principle in Java, it's really confused me. If so can someone explain how the UI is not being blocked?
Thanks
Edit:
The following code actually plays the Sequence
public static boolean Play() {
if(!_sequencer.isRunning()) {
try {
_sequencer.setSequence(_sequence);
_sequencer.start();
return true;
} catch (Exception e) {
Logger.Add(e.getMessage());
}
}
return false;
//Already running
}
Yes, it is the same theory. Only the Event Thread can modify the UI, and thus if you are doing anything on that thread, then you are preventing other events from working on the UI.
It may be easier to think about the Event Thread as a queue:
Show Form
Click Button
Do your work (Action)
Reset focus of Button
Update Progress Bar
Et cetera
If #3 takes long, then it may mean that your form will appear locked up. Obviously it completely depends on your definition of long. In general, it's better to work off of the Event Thread rather than on it.
It's definitely the same principal. Generally speaking you want to only do minimal work with the UI thread. If it ends up taking any significant time, it can cause the UI to be unresponsive and you can get a "Not Responding" error. You want to keep the UI thread as free as possible so it can respond to user interaction.
If your application has a graphical user interface, it's advised that you perform expensive calculations on a new Thread to keep your graphics from freezing. You can either create a SwingWorker, or use the Callable/Future idiom.
Yes, you're right. Read Threads and Swing for more info.
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.
Here is what I am trying to do:
I have a JFrame containing a JTextArea displaying updates on an on going connection. The user is supposed to be able to press the JButton to the right of it if they want to cancel the connection. However, since the connection is blocking (using) the thread while trying to connect, the GUI becomes frozen. I am looking for a quick fix. Having the ActionListener on a separate thread possibly? I do not have much experience with threads though I can make basic use of runnables.
Does the answer have something to do with using the EDT? If so how should this be implemented?
PS for clarification, the button should be able to kill a thread creating the connection. After reading it seems that an executorService. could help with this? Yes? or not at all?
It would be advisable to first get up to speed regarding Swing (or virtually any UI framework) and multi-threading. This is the napkin version:
Any modifications to the UI or reads from it (e. g. to get the value of a textfield) must be done only on the UI thread (which is also sometimes called the "Swing Thread" or "Event Dispatch Thread" (EDT)
Any blocking or long-running operations - like network communications - must NOT be run on the UI thread. Otherwise they will prevent buttons from working, texts from being updated etc.
In Java, the ExecutorService and its friends will make it relatively easy to let long-running or blocking stuff run on a background thread
If something happens on the background thread that requires you to update the UI, encapsulate the UI-related code in an EventQueue.invokeLater call. This will make sure the Runnable you pass gets executed on the UI thread.
The SwingWorker class encapsulates this logic and provides an easy to use helper for simpler cases.
When doing this the first time, it can be a bit daunting, but it pays off to understand this thoroughly, because it does not only apply to Swing, but to any other UI code, too.
for clarification, the button should be able to kill a thread creating the connection. After reading it seems that an executorService. could help with this? Yes? or not at all?
yes
while(localBooleanVariable) inside Runnable#Thread, plain Thread
by using SwingWorker.cancel()
easiest could be SwingWorker, because is cancelable and output from publish(), progress() is on EDT
Here is what I am trying to do:
I have a JFrame containing a JTextArea displaying updates on an on going connection. The user is supposed to be able to press the JButton to the right of it if they want to cancel the connection. However, since the connection is blocking (using) the thread while trying to connect, the GUI becomes frozen. I am looking for a quick fix. Having the ActionListener on a separate thread possibly? I do not have much experience with threads though I can make basic use of runnables.
Does the answer have something to do with using the EDT? If so how should this be implemented?
PS for clarification, the button should be able to kill a thread creating the connection. After reading it seems that an executorService. could help with this? Yes? or not at all?
It would be advisable to first get up to speed regarding Swing (or virtually any UI framework) and multi-threading. This is the napkin version:
Any modifications to the UI or reads from it (e. g. to get the value of a textfield) must be done only on the UI thread (which is also sometimes called the "Swing Thread" or "Event Dispatch Thread" (EDT)
Any blocking or long-running operations - like network communications - must NOT be run on the UI thread. Otherwise they will prevent buttons from working, texts from being updated etc.
In Java, the ExecutorService and its friends will make it relatively easy to let long-running or blocking stuff run on a background thread
If something happens on the background thread that requires you to update the UI, encapsulate the UI-related code in an EventQueue.invokeLater call. This will make sure the Runnable you pass gets executed on the UI thread.
The SwingWorker class encapsulates this logic and provides an easy to use helper for simpler cases.
When doing this the first time, it can be a bit daunting, but it pays off to understand this thoroughly, because it does not only apply to Swing, but to any other UI code, too.
for clarification, the button should be able to kill a thread creating the connection. After reading it seems that an executorService. could help with this? Yes? or not at all?
yes
while(localBooleanVariable) inside Runnable#Thread, plain Thread
by using SwingWorker.cancel()
easiest could be SwingWorker, because is cancelable and output from publish(), progress() is on EDT
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 writing a simple top down space game, and am extending it to allow play over a network with multiple players. I've done a fair bit of reading, but this is the first time I've done this and I'd appreciate some advice on choosing a sensible design.
My GUI is written using Swing. 30 times a second, a timer fires, and repaints my GUI according to data in a gameWorld object in memory (essentially a list of ships & projectiles with positions, etc). Physics updates of the gameWorld are also carried out using this timer. Thus, for the single player implementation, everything happens on the EDT, and this works fine.
Now, I have separate thread dealing with incoming packets from other players. I would like to update the data in my gameWorld object based on what these packets contain. My question is, should I use invokeLater to make these changes, or should I use locks to avoid concurrency problems?
To illustrate what I mean:
runMethodOfInputThread() {
while(takingInput) {
data = receiveAndInterpretIncomingPacket(); // blocks
SwingUtilities.invokeLater(new Runnable() {
public void run() {
gameWorld.updateWithNewGameInfo(data);
}
});
}
}
vs
runMethodOfInputThread() {
while(takingInput) {
data = receiveAndInterpretIncomingPacket(); // blocks
synchronize (gameWorldLock) {
gameWorld.updateWithNewGameInfo(data);
}
}
}
The latter would also require using similar synchronize blocks wherever the EDT accesses the gameWorld, so it seems to me that using invokeLater would be simpler to implement. But am I right in thinking both approaches would work? Are there any other significant pros/cons to bear in mind?
Thanks,
Jeremy
Well, first of all you don not need to choose only one method. You can use locks to make you data structure thread-safe "just to be sure" (since your application is already multithreaded), and use invokeLater to actually apply changes only in EDT -- and in this case JIT likely to optimize you locks down, close to 0.
Next, from my point of view invokeLater is rather preferred way: if you can way around dealing with multi-threaded -- you should use the way, just because multithreading is hard and rich of possible errors.
But applying changes via invokeLater() will put additional pressure on EDT, so, if changes come with high rate you can observe GUI degradation. Also, if gameWorld.updateWithNewGameInfo(data) is havy method taking observable time to complete, it can makes you GUI even freeze. Also, invokeLater puts your task at the tail of event queue, so it'll be done after all events currently in queue. It may -- in some cases -- cause delays in applying changes, which can makes you game less user-friendly. It may, or may not be your case, but you'll should keep it in mind
As for general rule -- not use EDT for any time consuming task. As far, as I understand, network packet parsing is already in seperate thread in your application. Applying changes can (and should) be done in separate thread too, if it is time consuming.
Pros for approach 1:
Minimized complexity
Stability
By restricting access to the 'gameWorld' variable to the EDT thread, locking mechanisms are not required. Concurrent programming is complex and requires the programmer(s) to be vigilant throughout the source base when accessing objects shared amongst threads. It is possible for
a programmer to forget to synchronize in certain instances, leading to compromised game states or program failure.
Pros for approach 2:
Scalability
Performance
Minimizing the processing done on the EDT thread ensures that the games interface and display will remain responsive to the user. Approach 1 may work for now, but later revisions of your game will not be able to scale to a more advanced interface if the EDT thread is busy doing non-ui processing.
Not the second one. You want to have as little as possible running in the EDT. If you are waiting for a lock in the EDT, it's as bad as running all the other code (on the other side of the lock) directly in the EDT since the EDT has to wait for everything else to finish.
Also, it seems that your whole game is running on the EDT. That's bad practice. You should split your code using the model-view-controller pattern. I understand your game is small and can run in the EDT, but you should probably not get into the habit.
You should have your game logic running from a timer thread (java.util.concurrent.ScheduledThreadPoolExecutor) and at the end of every period you "send" your data to the EDT and repaint with invokeLater.
You should also have some separate thread that reads the socket and that thread should write to objects that share locks with the objects you are using in the timer game thread.
My suggestion is as follows
push all loaded data from different users (thread) to a queue
use another thread to read from that queue and update UI from EDT
It should avoid your concurrency issue. How it can be achived
runMethodOfInputThread() {
while(takingInput) {
data = receiveAndInterpretIncomingPacket(); // blocks
blockingQueue.add(data);
}
}
runMethodOfUPdateUIThread() {
while(updatingUI) {
data = blockingQueue.take();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
gameWorld.updateWithNewGameInfo(data);
}
});
}
}