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();
or if no Swing components are being created/modified:
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