Pausing in Java - java

So I'm a beginning programmer and I'm trying to make a pong game(but horizontal). There is only one slight problem. After the user has scored a point the ball will immediatly return to the player. I would like to know if there's a way to start a little delay to give the player some time to react. Here is the 'scoring' system I'm using.
Thank you in advance!
if(yBall<=100-barHeight*0.5){
yBall = 300;
xBall = 400;
text_player2 = text_player2+1;
yBallSpeed = yBallSpeed *-1;
xBar = width*0.5 - barWidth*0.5;
//pause for few seconds
}

You can use Thread.sleep(millisecs), see https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#sleep%28long%29
Note, that you "have to put" Thread.sleep(millisecs) in a try-catch block (or add throw to the method):
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {}

In Java you can make the currently executing Thread go to sleep for x milliseconds using
Thread.sleep(1000);
If this is a beginner programming excercise then this might do for you. Make sure you catch the exception that this method throws.
Also please think about if you really want to sleep the thread the game runs on. Maybe you want to keep processing user input (e.g. if he wants to quit) but schedule the new ball bit later. For that, you can check out what Timer is for

It appears that you're doing this in a per-frame operation of your game, so Thread.sleep would be bad practice. Instead of pausing the game, it will make the game hang unresponsively for a certain time period (this may or may not be ok for yours).
Consider using System.currentTimeMillis() instead, which returns the current time in milliseconds:
long deadLine = 0L;
// Your method for updating the game's state
void updateState() {
if (deadline > System.currentTimeMillis()) {
// The game is currently paused. Draw a "Get Ready" string maybe?
return;
}
if (gameShouldRestart()) {
// The game should not do anything for the next two seconds:
deadLine = System.currentTimeMillis() + 2000L;
// Reset game state here.
}
}
Now the updateState() method will return immediately and let the game keep rendering but without doing anything, instead of just lagging the game for several seconds.

You should use a ScheduledExecutorService to invoke an action after a delay without causing the current thread to block. Try to reuse the same ScheduledExecutorService across your whole application, and make sure you shut it down at the end.
final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
try {
executor.schedule(() -> SwingUtilities.invokeLater(() -> {
readyToRestart(); // your method that restarts the action
}), 1, TimeUnit.SECONDS);
} finally { executor.shutdown(); }
Since the ScheduledExecutorService will run the scheduled action on its own thread, you will need to make sure the action does not cause any threading related problems. How you do this depends on what GUI toolkit you are using. In the example I show how to do it in Swing using the SwingUtilities.invokeLater method.

Related

Java asynchronously wait x seconds

To give some details about what I'm trying to do: I'm making a Minecraft plugin in Java. I have an Object which is bound to the Player object of Minecraft using a HashMap.
I have a method in this object which is something like:
public void faint() {
... //Apply the effect on the player
//wait for x seconds, and if the player didn't already wake up, wake them up. (player.wakeUp())
}
Obviously, there will be a lot of stuff going on, so I want this to happen asynchronously. The timer will go on in the background and it won't block anything else in the code.
Sorry if my question is too simple, but I really checked the web and I'm new to Java, so forgive my ignorance.
You can create a separate thread by implementing a Runnable interface like this and do the delay in there.
// This is happening in the main thread
Thread thread = new Thread(){
public void run(){
// This code will run async after you execute
// thead.start() below
Thread.sleep(1000)
System.out.println("Time to wake up");
}
}
thread.start();
Use the Bukkit scheduler.
Bukkit.getScheduler().runTaskLater(yourPluginInstance, () -> {
// put code here to run after the delay
}, delayInTicks);
When the code runs after the delay it will run on the main server thread.

Java does something for 15 seconds and then something else 5 sec after

So I wanted to implement a timer that would allow me to draw a red square every 15 seconds and then after it was there for 5 seconds make the square disappear from the canvas. It is a trap in the game that I want to implement, but am not sure how the timer would work.
I figured I need 2 timers one for the appearing, and the second for disappearing(?) but am not sure how to sync them so that the square appears and stays at a position of the canvas for 5 seconds in 15 second periods either. (it might even be better to have it in a random 15-20 second increment of time). It's important that this item disappears after I turn the canvas from say red to white.
How does calling a timer in a function work? Do I need a new class for this? Is an instance variable enough?
We're missing some important details (like which framework you're using), but the basic idea would be...
Have a single "main loop" which is responsible for updating the state of the game and scheduling updates to the UI
Have a List of "event"s which are designed to be triggered at a given point in time, have the "main loop" check these events (maybe ordered in time order to make it more efficient to iterate) and trigger the ones which need to be triggered based on the current time and the time of the event (this would obviously remove the event from the List)
Events could create new events, so for example, when your trap door event is triggered it could trigger a "remove" event for 5 seconds in the future. Equally, when the remove event is triggered, if could trigger a new "trap door" event
This way, you could have any number of trap doors appearing at random intervals.
Remember, more thread's/timer doesn't equate to better performance and would also increase the overall complexity of your problem, as you'd need to put in a series of checks to ensure everything stayed on sync
Being a java graphic application I would just create instances of SwingWorker and fire it when needed. Every SwingWorker would start with an appropriate sleep call (https://docs.oracle.com/javase/tutorial/essential/concurrency/sleep.html). Have a look at the Swing documentation in order to create proper SwingWorkers that run in the background, waiting and doing later the task you need (https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html).
You could create a new thread making all the timer work.
But this segment into the place the timer is needed:
new Thread(new Runnable()) {
#override
public void run() {
while(true) {
// do the drawing stuff
try {
sleep(5000); // make the thread wait 5000 microsecs = 5s
} catch (InterruptedException ex) {}
// do deleting stuff
try {
sleep(15000);
} catch (InterruptedException ex) {}
}
This starts a new thread repeatedly doing the create-, wait-, delete- and wait-process.

What can be the best technique to Terminate the Execution of Program based on some event in Java

I am designing a Card based Game in Java. I have implemented the game logic. It is working fine. Now I want to add a functionality which can check for the time player is playing the game. If the time goes above a threshold limit, I want to terminate the Execution of Game. Please suggest me what should be the best strategy to implement this feature? Is creating a Thread and checking the time a good technique or there is any other technique to achieve this?
Edit: Sorry for the vague description.What I want to implement is, no matter where the player is in the execution sequence, when the time limit reaches, program should terminate. If i implement the check at the looping condition, then if the time is still left, program will continue and complete the set of instructions in the loop, but if the time is over even if the program is entered into the execution loop, it should stop doing whatever it is doing. This is what i want to implement.
Thanks,
Tara Singh
Two possibilities:
If you're using some sort of main loop where all the processing takes place, just add a check for the amount of time passed in there.
You can create a Timer that runs when the time is up and executes some method that ends the game. The timer will take care of creating another thread and executing it for you. Have a look at: http://download.oracle.com/javase/6/docs/api/java/util/Timer.html
I guess checking the elapsed time here and there would be sufficient, but if you want to use threading, here is a simple way to do it. You can also use Timer instead of creating your own thread. The idea is same; TimerTask should interrupt the main thread when the timeout happens.
class Main {
public static void main() throws Exception {
final long timeout_ms = TimeUnit.MINUTES.toMillis(60);
//Store the main thread ref. so the interruption task can use it
final Thread me = Thread.currentThread();
new Thread(){
#Override
public void run(){
// If the timeout happens, or this thread is interrupted
// due to VM termination etc.) interrupt the main thread.
try{
Thread.sleep(timeout_ms);
}catch(InterruptedException e){
//see finally block
}finally{
me.interrupt();
}
}
}.start();
// Executing the game in the main thread.
new Game().run();
}
}
and then
class Game implements Runnable {
#Override
public void run(){
// Basically, check for the interruption flag before you do
// something that takes time to execute.
while(!Thread.currentThread.isInterrupted()){
doSomething();
}
}
}
Using the interruption flag is the preferred way to solve this kind of problem. One of the advantage of using interruption flag instead of creating your own signaling flag, or checking for elapsed time in the loop itself is that you can utilize the interruption support of other APIs.
For example, you might use Thread.sleep() in your game. If you don't use the interruption mechanism, you must wait until sleep() returns. If you do use the interruption mechanism, sleep() will immediately return, throwing InterruptedException, so your app. will be more responsive.
Whenever you catch InterruptedException in your app. handle it as follows unless you have specific reasons:
try{
someMethod();
}catch(InterruptedException e){
//Restore interruption flag
Thread.currentThread.interrupt();
//If you have some clean up to do, do it here.
return;
}
Whenever the app. throws InterruptedException you have to "restore" the interruption flag in order to relay the interruption message up the stack because InterruptedException will "clear" the interruption flag (to false).
How are you keeping the game going in the first place? If, as I suspect it is with some sort of loop then why not allow the loop to terminate given the time condition?

Java: Stopping a thread that has run for too long?

Say I've got something like this
public void run(){
Thread behaviourThread = new Thread(abstractBehaviours[i]);
behaviourThread.start();
}
And I want to wait until abstractBehaviours[i] run method has either finished or run for 5000 milliseconds. How do I do that? behaviourThread.join(5000) doesn't seem to do that afaik (something is wrong with my code and I've put it down to that).
All the abstract abstractBehaviour class is of course Runnable. I don't want to implement it inside each run method as that seems ugly and there are many different behaviours, I'd much rather have it in the calling/executing thread and do it just once.
Solutions? First time doing something as threaded as this. Thanks!
edit: So the interrupting solution would be ideal (requiring minimal changes to AbstractBehaviour implementations). BUT I need the thread to stop if it has finished OR 5000 milliseconds have passed so something like the following would not work because the thread may finish before the while loop in the parent thread has. Make sense? Any ways around this, I'd love to do it from within the thread that starts the threads obviously.
long startTime = System.currentTimeMillis();
behaviourThread.start();
while(!System.currentTimeMilis - startTime < 5000);
behaviourThread.interrupt();
try {
behaviourThread.join();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
edit: nevermind I see there is a Thread.isAlive() method, all solved I think
The best way to do this is to use the thread interrupt mechanism. The worker thread / Runnable needs to periodically call Thread.interrupted() to see if it is time to stop. The second part of the equation is that a separate thread needs to call Thread.interrupt() on the worker thread after 5000 milliseconds have elapsed.
The advantages of using thread interrupts (over a bespoke solution using flags) include:
The interrupted() state is always available for the current thread. You don't need to pass around an object handle or use a singleton.
An interrupt will unblock some blocking IO and synchronization requests. A bespoke solution cannot do this.
Third-party Java applications and libraries may respect Thread.interrupt().
EDIT - as a commenter points out, you can test whether the current thread has been interrupted using either Thread.interrupted() or Thread.currentThread().isInterrupted(). The main difference between the two approaches is that the former clears the interrupted flag, but the latter doesn't.
You cannot do this externally from the run method - the run method must check some variable to see if it should exit. For example:
class InterruptableRunnable implements Runnable
{
private volatile boolean stop;
public setStop() {
stop = true;
}
public void run() {
while (!stop)
{
//do some work and occassionaly fall through to check that stop is still true
}
}
}
The key thing is for the code in the run loop to check the stop flag occasionally. You can then wire up a timer to set stop to true after 5000 milliseconds.
Finally, it's best practice not to use Threads directly, use the excellent Concurrency Framework. The Concurrency Tutorial is a good place to start and the book Java Concurrency in practice is excellent.
You may do it using java.util.concurrent package.
ExecutorService service = Executors.newCachedThreadPool();
Future future = service.submit(behaviourThread);
long startTime = System.currentTimeMillis();
while (!future.isDone()) {
if (System.currentTimeMillis() - startTime > 5000) {
future.cancel(true);
break;
}
}
// TODO: more work here
//don't forget to shutDown your ThreadPool
service.shutDown();
This code will stop your thread after 5 seconds if it has not finished it's job by that time. If you check behaviourThread.isAlive() it's gonna show false.
You do that by implementing a Runnable
public void run()
{
long time = System.nanoTime(),
end = time + 5 000 000 000; // just better formatting
do {
...my code
} while (System.nanoTime() < end && myOwnCondition);
}
Interrupt is not such a good solution, because you need to access the thread from outside
and it disturbs the program flow. The thread can terminate anytime in your code which
makes cleanup difficult. Please form a habit of letting threads run to the end because otherwise it opens nasty and difficult bugs.
If your program is so heavy duty that you don't know that the while end is reached until the task has completed I suggest the use of a labeled break:
do {
breakout:
{
..my code
if (timetest)
break breakout;
}
// cleanup
...
} while (...);

How can I stop a Java while loop from eating >50% of my CPU?

Okay, I tested this on an empty program, and just having a while(true){} running gave me >50% on my CPU. I have a game I'm working on that uses a while loop as it's main loop, and it's CPU is at 100 all the time.
How can I get Java to repeat something over and over without eating up >50% of my CPU just to do the repeating?
Add a sleep to put the thread into idle for some interval:
Thread.sleep
Without having a sleep, the while loop will consume all the computing resources that is available. (For example, theoretically, 100% in a single core system, or 50% in a dual core, and so on.)
For example, the following will cycle once through a while loop approximately every 50 milliseconds:
while (true)
{
try
{
Thread.sleep(50);
}
catch (Exception e)
{
e.printStackTrace();
}
}
This should bring down the CPU utilization quite a bit.
With a sleep in the loop, the operating system will also give enough system time for other threads and processes to do their things, so the system will be responsive as well. Back in the days of single core systems and operating systems with not-so-good schedulers, loops like this could have made the system very unresponsive.
Since the topic of use of while loops for a game came up, if the game is going to involve a GUI, the game loop must be in a separate thread or else the GUI itself will become unresponsive.
If the program is going to be a console-based game, then threading is not going to be an issue, but with graphical user interfaces which are event-driven, having a long-living loop in the code will make the GUI unresponsive.
Threading and such are pretty tricky areas of programming, especially when getting started, so I suggest that another question be raised when it becomes necessary.
The following is an example of a Swing application based in a JFrame which updates a JLabel that will contain the returned value from System.currentTimeMillis. The updating process takes place in a separate thread, and a "Stop" button will stop the update thread.
Few concepts the example will illustrate:
A Swing-based GUI application with a separate thread to update time -- This will prevent lock up of the GUI thread. (Called the EDT, or event dispatch thread in Swing.)
Having the while loop with a loop condition that is not true, but substituted with a boolean which will determine whether to keep the loop alive.
How Thread.sleep factors into an actual application.
Please excuse me for the long example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TimeUpdate
{
public void makeGUI()
{
final JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JLabel l = new JLabel();
class UpdateThread implements Runnable
{
// Boolean used to keep the update loop alive.
boolean running = true;
public void run()
{
// Typically want to have a way to get out of
// a loop. Setting running to false will
// stop the loop.
while (running)
{
try
{
l.setText("Time: " +
System.currentTimeMillis());
Thread.sleep(50);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
// Once the run method exits, this thread
// will terminate.
}
}
// Start a new time update thread.
final UpdateThread t = new UpdateThread();
new Thread(t).start();
final JButton b = new JButton("Stop");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
t.running = false;
}
});
// Prepare the frame.
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(l, BorderLayout.CENTER);
f.getContentPane().add(b, BorderLayout.SOUTH);
f.setLocation(100, 100);
f.pack();
f.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new TimeUpdate().makeGUI();
}
});
}
}
Some resources about threading and using Swing:
Threads and Swing
Lesson: Concurrency
Thread.Sleep may not be the whole answer. For most games, there's way too much CPU for the amount of work needed. Simply sleeping for a set amount of time isn't all that efficient, since you will likely either still burn too many resources, or not enough. You typically want to time your work in some way.
If you think about it, the screen only updates at a certain rate, typically less than 100 times per second. I'm not familiar with the Java api's for this sort of thing, but what you want is to find out the refresh speed of the monitor and then update only a single time between each refresh.
Further, you don't need a loop like that for your main loop, you can use timers to call your update code at a regular interval. This is even more efficient.
You are indeed busy-waiting, meaning you are grinding your CPU constantly on checking one or more conditions until they are true.
Thread.sleep() is not the solution. Using wait() and notify() methods allows you to do just what you are trying, but much more efficiently. Basically, this mechanism allows a thread to sleep on an object until the object decides something has happened and wants to wake all the threads sleeping on it.
Code exmaples can be found here and here.
This should be your solution, and not hiding your busy-wait with a timer.
While yes, you could do a
Thread.sleep(50)
like the accepted answer suggest, you could also call
Thread.sleep(0)
This will tell the processor to do a context switch. Other threads waiting to be executed (like the GUI drawing thread) will then be executed and the machine will stop feeling slow.
The sleep(0) way will also maximise the time given by the OS to you application because the thread will immediatly go back in the processor's queue (instead of waiting 50ms before doing so) so if no other thread where waiting, you thread will continue being executed.
Usually in a game loop you will pause for a bit... for example: http://developers.sun.com/mobility/midp/articles/game/
It seems like your thread is busywaiting. That is to say, it is trapped in a loop in which it does nothing. In such a situation, it will chew up a lot of cpu cycles to no effect.
As mentioned by others, Thread.sleep is the answer.
That's swing-related, but the idea stays the same: try to use Observer pattern instead of wile(true).
How about a Quartz-Spring based scheduler that keeps doing the work over and over again in repeated intervals.
If there is an interrupt it is probably for a reason. A better way to handle this is
try {
while (true) {
Thread.sleep(50);
}
} catch (InterruptException e) {
Thread.currentThread().interrupt();
}
However this loop doesn't do anything, so I suggest you just delete it. It is fairly rare that you want to busy wait for a condition (In which case the Condition class is a better choice) usually you can transform the same behaviour not to need a loop at all.

Categories