I ran into what would SEEM to be a deadlock. Does a deadlock sound a little like:
Can't close window
Can't terminate without terminate button on the IDE
Blank and nothing happens, with no Exceptions or errors at all.
if those are the things that happen in a deadlock, then I probably have half the problem solved already. I have two threads that I know of are running: AWT-EventQueue-0 and frameThread.
This is using a custom library that I built and isn't fully developed yet (what you might call alpha-beta stage?). I decided to use it to make a Pong game. Actually my mentor assigned me the game. I'm just going to use my library with it.
My library uses Swing components and I doubt that has anything to do with it.
I would like to point out that the intrinsic locks according to the oracle tutorials state that
"When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns. The lock release occurs even if the return was caused by an uncaught exception."
before doing what this says, I had done a synchronized block to acquire the lock from the only thread I know of in my program that could have the lock. Failed. So I made the method synchronized and, well, the bullet points listed above happened.
my code is
// Threads
static ThreadManager tm = new ThreadManager() {
#Override
protected void runFrameThread() {//ThreadManager has threads in it that you can start.
while (true) { //These are just the abstract inherited methods the
Main.jpane.repaint(); // threads inside the manager call
}
}
#Override
protected void runMathThread() {
}
#Override
protected void runIntenseMathThread() {
}
};
// set frame rate
static {
tm.setFPS(30L);
}
public synchronized void draw(Graphics g) {// main problem: synchronized method here.
try {
wait(hertz);
} catch (InterruptedException e) {
System.err.println("ERROR: " + e.getLocalizedMessage());
e.printStackTrace();
}
g.setColor(rgb);
g.fillRect(this.x, this.y, width, height);
}
if that doesn't help, you can try looking through my code...
My Code Repository for the Pong game
My best bet is its something wrong with what Im doing to delay the method. what I want to do is have an update rate for every object at a set rate of 'x' hertz. It would be easier if it was a return type method (not void).
You state:
My library uses Swing components and I doubt that has anything to do with it
I fear that you may be very wrong. You appear to be completely blocking the Swing event dispatch thread (the EDT) with your while loop, and since this thread is responsible for all Swing graphics and user interaction, this will effectively freeze your GUI.
Rather than a while (true) loop that will block the EDT, use a Swing Timer instead.
Don't pause your graphics drawing as this will make your program seem poorly responsive.
Don't call synchronize from within a painting method.
Don't change the state of your objects from within a painting method such as paintComponent (i.e., don't call your updateGame() method from within paintComponent). This is because you never have full control over whether or even if this method will be called. It can be called out of your control by the JVM in response to a request by the OS to clean a dirty region, and the JVM may ignore your request for a repaint if repaint requests are stacking up.
This does appear to be a deadlock, and it most certainly has something to do with the use of Swing. The symptom of the whole application hanging is usually caused by the event dispatch thread (EDT) being deadlocked.
The problem appears to be in this code, which is in your Ball.java class:
public synchronized void draw(Graphics g) {
try {
wait(hertz);
} catch (InterruptedException e) {
...
}
It appears that the hertz field is not explicitly initialized, and thus it has its default value of 0L. A value of zero for the wait(timeout) method will block indefinitely, that is, it will wait with no timeout. It doesn't appear that this object is ever notified, so this method will hang the calling thread forever. This method is called from the JPanel.paintComponent method, which is called by the EDT, so this freezes the application's user interface.
Don't try to control the update rate by sleeping or pausing within the painting routines. The painting routines should always do as little work as possible, inspecting the current state of your model and issuing the appropriate graphics calls, and returning as quickly as possible.
Your program is multi-threaded, so you will need to synchronize your objects. The thread manager threads are updating the game objects and the EDT is painting using the game objects.
Access to your objects will occur on multiple threads, thus the need for synchronization. The synchronized blocks (or methods) should do as little as possible: get in, update (or paint), and get out. Code on the EDT should never call wait as that will probably cause poor repaint performance and responsiveness. The update threads should do as much computation as possible outside of the lock, and simply update the game objects with new values while the lock is held. This will minimize the amount of time the EDT is blocked acquiring the lock during the repaint cycle.
Related
I am fairly new to java, and am starting to get into using different threads in order to use wait() or sleep() on one part of my code and have the others still run.
For this project, I am using JFrame with the javax.swing.* and java.awt.* imports. What I am trying to do is have one of the threads (in my code it is the main, starting thread) allow the player to choose a space on the tic tac toe board, and when they click it, it will change icons, and then the AI will wait for 1 second before playing back from the second thread that I created.
Unfortunately, whenever I call ait.sleep(1000) (ait is my thread name) both threads wait for 1 second before finishing their execution. Can anyone tell me why sleeping one thread is stopping my whole execution?
Can anyone tell me why sleeping one thread is stopping my whole
execution
to better explain your Swing GUI is created on its own special thread separate from that which main() and other code will run in, this is done via creating your Swing components in the SwingUtilities.invokeXXX block (even if you have not done this your GUI will be run on a single thread called the initial thread) . Now if you simply call sleep while on Event Dispatch Thread (or for that matter on the same Thread) it will wait for the call to Thread.sleep to finish. Now because all Swing events are processed on EDT we pause its execution by calling sleep(..) thus pausing the UI events from being processed and therefore GUI is frozen (until sleep(..) returns).
You should not use Thread.sleep(..) on Event Dispatch Thread (or any Thread where sleep will cuase unwanted execution blocking), as this will cause the UI to seem frozen.
Here is a nice example which demonstrates exactly, this unwanted behavior caused by invoking Thread.sleep(..) on GUI's EDT.
Rather use:
Swing Timer for example:
int delay=1000;// wait for second
Timer timer = new Timer(delay, new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
//action that you want performed
}
});
//timer.setRepeats(false);//the timer should only go off once
timer.start();
Swing Worker
or if no Swing components are being created/modified:
TimerTask
Thread, you would then use Thread.sleep(int milis) (but thats last option in any case IMO)
UPDATE
Swing Timer/SwingWorker was only added in Java 1.6, however, TimerTask and Thread have been around for alot longer sine Java 1.3 and JDK 1 repsectively, thus you could even use either of the 2 above methods and wrap calls that create/manipulate Swing components in SwingUtilities/EventQueue#invokeXX block; thats the way things used to be done :P
Thread.sleep is a static method. Invocations of it via the reference of any given Thread is simply a form of convenience.
As a result, any invocation of sleep is really calling sleep on the current Thread, which I suspect is the Event Thread in your case. Sleeping/blocking on the Event Thread will give the appearance of being locked up.
If you want the ait thread to sleep, then code that thread to sleep. Designs where one thread "reaches into" another and pushes it around at a low level are fundamentally broken. You write the code for every thread, so write it to do what you want it to do in the first place so you'll find no need to reach into it from the outside.
Which makes more sense, for the person in the kitchen to know how to cook breakfast or the person in the bedroom to yell down and direct them to perform each step of making breakfast? Sure, you might tell them to make breakfast. But you definitely don't direct each step at a low level.
Thread.sleep is a static method which causes the currently executing thread to sleep for the specified amount of time. Java syntax allows you to call a static method via a variable, but the compiler simply uses the compile-time type of that variable to determine which method to call, i.e.
Thread ait = null;
ait.sleep(1000); // calls Thread.sleep(1000), causing current thread to sleep.
// In particular, does *not* NPE
You also mentioned wait() - while this is an instance method rather than a static it still causes the current thread to do the waiting (ait.wait(1000) would cause the current thread to wait for up to 1 second or until another thread calls ait.notifyAll()).
There is a Thread.suspend() and its counterpart resume() that were introduced in the very early days of Java to allow one thread to control another, but they were deprecated soon after as they are inherently deadlock-prone. The recommended pattern if you want one thread to "control" another is to do it co-operatively, i.e. have some kind of shared flag that thread A sets and thread B reads, and have B send itself to sleep according to the flag:
volatile boolean threadBShouldRun = true;
// Thread B
while(true) {
if(threadBShouldRun) {
// do some stuff
} else {
Thread.sleep(1000);
}
}
// Thread A
if(someCondition) {
threadBShouldRun = false;
}
but it's generally easier and less error-prone to make use of the facilities that exist in the java.util.concurrent package. Doing multi-threading right is much harder than it appears on the surface.
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 am fairly new to java, and am starting to get into using different threads in order to use wait() or sleep() on one part of my code and have the others still run.
For this project, I am using JFrame with the javax.swing.* and java.awt.* imports. What I am trying to do is have one of the threads (in my code it is the main, starting thread) allow the player to choose a space on the tic tac toe board, and when they click it, it will change icons, and then the AI will wait for 1 second before playing back from the second thread that I created.
Unfortunately, whenever I call ait.sleep(1000) (ait is my thread name) both threads wait for 1 second before finishing their execution. Can anyone tell me why sleeping one thread is stopping my whole execution?
Can anyone tell me why sleeping one thread is stopping my whole
execution
to better explain your Swing GUI is created on its own special thread separate from that which main() and other code will run in, this is done via creating your Swing components in the SwingUtilities.invokeXXX block (even if you have not done this your GUI will be run on a single thread called the initial thread) . Now if you simply call sleep while on Event Dispatch Thread (or for that matter on the same Thread) it will wait for the call to Thread.sleep to finish. Now because all Swing events are processed on EDT we pause its execution by calling sleep(..) thus pausing the UI events from being processed and therefore GUI is frozen (until sleep(..) returns).
You should not use Thread.sleep(..) on Event Dispatch Thread (or any Thread where sleep will cuase unwanted execution blocking), as this will cause the UI to seem frozen.
Here is a nice example which demonstrates exactly, this unwanted behavior caused by invoking Thread.sleep(..) on GUI's EDT.
Rather use:
Swing Timer for example:
int delay=1000;// wait for second
Timer timer = new Timer(delay, new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
//action that you want performed
}
});
//timer.setRepeats(false);//the timer should only go off once
timer.start();
Swing Worker
or if no Swing components are being created/modified:
TimerTask
Thread, you would then use Thread.sleep(int milis) (but thats last option in any case IMO)
UPDATE
Swing Timer/SwingWorker was only added in Java 1.6, however, TimerTask and Thread have been around for alot longer sine Java 1.3 and JDK 1 repsectively, thus you could even use either of the 2 above methods and wrap calls that create/manipulate Swing components in SwingUtilities/EventQueue#invokeXX block; thats the way things used to be done :P
Thread.sleep is a static method. Invocations of it via the reference of any given Thread is simply a form of convenience.
As a result, any invocation of sleep is really calling sleep on the current Thread, which I suspect is the Event Thread in your case. Sleeping/blocking on the Event Thread will give the appearance of being locked up.
If you want the ait thread to sleep, then code that thread to sleep. Designs where one thread "reaches into" another and pushes it around at a low level are fundamentally broken. You write the code for every thread, so write it to do what you want it to do in the first place so you'll find no need to reach into it from the outside.
Which makes more sense, for the person in the kitchen to know how to cook breakfast or the person in the bedroom to yell down and direct them to perform each step of making breakfast? Sure, you might tell them to make breakfast. But you definitely don't direct each step at a low level.
Thread.sleep is a static method which causes the currently executing thread to sleep for the specified amount of time. Java syntax allows you to call a static method via a variable, but the compiler simply uses the compile-time type of that variable to determine which method to call, i.e.
Thread ait = null;
ait.sleep(1000); // calls Thread.sleep(1000), causing current thread to sleep.
// In particular, does *not* NPE
You also mentioned wait() - while this is an instance method rather than a static it still causes the current thread to do the waiting (ait.wait(1000) would cause the current thread to wait for up to 1 second or until another thread calls ait.notifyAll()).
There is a Thread.suspend() and its counterpart resume() that were introduced in the very early days of Java to allow one thread to control another, but they were deprecated soon after as they are inherently deadlock-prone. The recommended pattern if you want one thread to "control" another is to do it co-operatively, i.e. have some kind of shared flag that thread A sets and thread B reads, and have B send itself to sleep according to the flag:
volatile boolean threadBShouldRun = true;
// Thread B
while(true) {
if(threadBShouldRun) {
// do some stuff
} else {
Thread.sleep(1000);
}
}
// Thread A
if(someCondition) {
threadBShouldRun = false;
}
but it's generally easier and less error-prone to make use of the facilities that exist in the java.util.concurrent package. Doing multi-threading right is much harder than it appears on the surface.
I have running thread that I would like to stop and later on resume at some point. I learned not to use stop() etc. as these are deprecated and got to this code below that seems to stop thread successfully. It simply exits run method. Now, how can I restart it? If I call start() method it says that thread is still running, so would directly calling run() do in this situation? Would it cause any problems? BTW this is for Android app if that makes any difference.
private volatile stopThread;
public void stopButton() {
// this is called when button is clicked
// and thread is already started and running
stopThread= true;
}
public void run() {
while (!stopThread) {
// do something here
}
stopThread=false;
}
EDIT: its a timer that starts when thread is started, then can be paused and started again. So timer is a class containing Thread object (I already extend the class with SurfaceView).
The only safe way to stop and resume a thread safely is to add code at the relevant points in the thread's body to deal with it. (Don't use the deprecated Thread stop / pause / resume because they are fundamentally unsafe.)
Stop without resumption is relatively simple, using either an application-specific flag, or the Thread.interrupt() mechanism. The latter is probably better because some of Java's synchronization and IO APIs are interrupt-aware. However, you do run against the problem that a lot of existing libraries are not interrupt aware, or don't deal with InterruptedException properly.
Stop with resumption is more tricky. You'll need to create your own class something like this:
public class PauseControl {
private boolean needToPause;
public synchronized void pausePoint() {
while (needToPause) {
wait();
}
}
public synchronized void pause() {
needToPause = true;
}
public synchronized void unpause() {
needToPause = false;
this.notifyAll();
}
}
and add calls to myPauseControl.pausePoint() at relevant points throughout your the thread's code. Note that this won't allow you to pause IO, or activity in "child" threads, and it will only pause at points in your code where you call the pausePoint method. Also you need to beware of creating problems by pausing the thread while it holds locks on something else, or while something else is waiting for it to respond.
The Java 1.4 docs explained why and gave alternatives to the various deprecated Thread methods, including suspend() and resume() by using wait() and notify() instead.
Look for the heading What should I use instead of Thread.suspend and Thread.resume? about halfway down the page.
The stop() method of Thread class is deprecated and unsafe for use, because stopping a Thread causes it to unlock all monitors that it had locked. This has damaging consequences, because any of the Objects (previously protected by monitors) in an inconsistent state may now be viewed by other threads in an inconsistent state. This behavior may be subtle and difficult to detect.
You never invoke the run() method directly and if you stop the Thread using your volatile variable approach, the Thread would have TERMINATED. In order to start the Thread perform new Thread().start() again.
I'm writing a game in which a thread - GameThread - loops forever, updating all my sprites, rendering them, and then sleeping for some time before doing it all again. I also have a custom-made Event handler which deals with key presses etc.
This all works fine in most cases. However I have a problem if an event is thrown while GameThread is rendering. On rare occasions, the handler that deals with the event may make a concurrent change to what needs to be rendered affecting the results of the GameThread rendering.
To avoid this, I want the event handler to pause the GameThread immediately, handle the event, then resume GameThread.
The suspend() / resume() methods suit my needs, but they were deprecated. In my case, however, as there is little chance of a deadlock, is it safe to use them regardless?
If no, what other alternatives do I have that don't have a huge amount of overhead?
I have seen a suggestion of requesting a thread to pause by setting a flag in the Thread to be paused. In my case, however, I don't see that as a viable option since the GameThread loop may take a while during an iteration through the loop. I won't be able to check the flag until I'm done with the loop and by then it is too late.
I need immediate pausing, or else the user will notice a delay in the event handling.
If you want to synchronize access to resources, use a ReentrantLock:
ReentrantLock sync = new ReentrantLock();
You'd have to pass that lock to each runnable where you want to access the shared data.
Then in each place you're accessing the resource in question, you would use that shared lock object, and obtain and release the lock (ie, your critical sections):
sync.lock();
try {
// critical section code here
}
finally {
sync.unlock();
}
This is pretty standard concurrent programming in java. Keep in mind "lock" is a blocking method, so you might want to use "tryLock" instead, which allows you to try and acquire the lock, but returns a boolean as to whether or not you actually got the lock:
if (sync.tryLock()) {
try {
//critical section
}
finally {
sync.unlock();
}
}
There's a version of "tryLock" which will wait a given amount of time, before it will give up trying to acquire the lock and return a false value.
Usually, you would do some thread synchronization:
http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
This would let you do one of the two things you are doing: either render in the game rendering thread or do the changes based on your events.
The problem you are facing seems to be that your rendering code is taking too long for you to actually have a smooth experience (i.e. a lot of events can pile up for processing while you are rendering something). In that case, you should make your rendering out of independent pieces that can finish quickly and synchronize on them.
Without any code I cannot give you a specific advice, however in general it would look something like this:
List<Shape> shapesToRender;
Object lockObject = new Object(); // Note this must be somehow shared between two threads
// Your rendering thread method
public void renderForever() {
while(true) {
for(Shape shape: shapesToRender) {
synchronized(lockObject) {
render(shape);
}
}
}
}
// One of your event handlers
public void handleEvent(Event event) {
synchronized(lockObject) {
// Process event somehow, e.g. change the color of some of the shapes
event.getShape().setColor(Color.RED);
}
}
With the above, either:
You will be rendering one shape (and all your event handlers will be waiting for that to finish), or
Some of your event handlers will be doing something (and your rendering thread will be waiting for that to finish)
You should look at this Java trail in more depth:
http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html
as there are other solutions, e.g. using lock objects:
http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html
or concurrent collections:
http://docs.oracle.com/javase/tutorial/essential/concurrency/collections.html
that, depending on your problem, might be easier and, most importantly, very well tested solutions that would allow you to do something in a standard way, thus avoiding all the pitfalls that you can get into when rolling out custom threading code.
Hope this helps.
The suspend() / resume() methods suit my needs, but they were deprecated. In my case, however, as there is little chance of a deadlock, is it safe to use them regardless?
Obviously, if there is ZERO chance of a deadlock then it is safe. But there are all sorts of unexpected ways to get a deadlock. For instance, you could happen to pause a thread while it is initializing a class ... and that would deadlock any other thread trying to refer to a static field of that class. (This is a consequence of a specified behaviour of the JVM. There are other places where the locking / synchronization that goes on under the hood is not specified. Fair enough. It doesn't need to be ... unless you are contemplating using these deprecated methods.)
So, the reality is that it is really difficult to determine (prove) if it is actually safe. And if you can't determine this, then it is a potentially risky thing to do. That's WHY the methods are deprecated.
(Strictly speaking, this is not a deadlock. A deadlock is when the threads can never proceed. In this case, the other threads can proceed if you can resume the paused thread.)