I'm currently trying to get a small brick-breaker game I made to effectively use some form of power-ups or bonuses. I have have it mostly implemented right now. However I have a problem. I use java.util.Timer to determine how long the power-up lasts. Most likely, that power-up is going to be chosen (by a random number generator) more than once. However, a Java Timer can only be used once, and after it's cancel() method is called, it's done. Right now, I set up the game to mark a power-up as used and to never use it again. Is there a way to get around this? Here's the method that is called when the LongPaddle power-up is chosen:
public void longPaddleTime(int seconds) { //longPaddle Timer Method - gets called when the longPaddle bonus is enabled; shuts off longPaddle after a set amount of time
timerLP.schedule(new TaskLP(), seconds*1000);
}
class TaskLP extends TimerTask { //The task to be run after the timer in longPaddleTime runs out
public void run() {
longPaddle=false; //Disable LongPaddle
bonusActive=false;
LPused=true; //Mark as used
timerLP.cancel(); //Terminate the timer thread
timerLP.purge();
}
}
You don't need to cancel() your timer - Timer.schedule(TimerTask, long delay) will only run the specified task once. You only need to cancel() a timer if you want to terminate everything it's doing.
For your case (scheduling a task once), there's no cleanup required in the Timer class. If you had a repeating task and you wanted to stop just that one task, you could call TimerTask.cancel() to prevent it from reoccuring, while still allowing the Timer to be reused for other purposes.
You don't have to cancel the timer in your TaskLP.
Create a Timer object that lives in Application scope and just schedule new TimerTasks as need arises.
BTW, although not officially deprecated, Timer functionality has been superseeded by ScheduledExecutorService. I suggest, if you start from scratch to use this framework.
Executors utility class has a few methods that simplify the construction of the ScheduledExecutorService.
Related
I have a couple different enemy types and enemyManager arrayList classes for each type. I have each type of enemy randomly spawning at spawn points slightly off screen, coming onto the screen, then off the other side, dying, and randomly responding. The problem is when I use a loop to spawn the objects many of them spawn in the same place or catch up with each other die around the same time and spawn again. I would like to have a delay between them so they are more spread out.
What I am looking for is a way to slow down the looped spawning of enemies in java. I tried extending enemy manager classes by timer and naming the spawn function run but this didn't work.
Also I am not multithreading because I don't really know how to set that up yet and was trying to finish this project without implementing that, but if that seems like the best solution then I guess I will have to.
thanks for any suggestions.
updated .....
class spawnLgCars extends TimerTask {
public void run() {
if (lgCars.size() < 10) {
lgCars.add(new LgCar());
System.out.println("spawned");
} else if (lgCars.size() > 10) {
lgCars.get(0);
}
}
}
Here I how I'd like to implement TimerTask, but because it had to be in it's own class it didn't have access to the properties of the instance of lgCars I was using. Then I tried adding extending lgCars by Timer Task and calling the task in the constructor, but this also didn't work. not sure why.
TimerTask and a java.util.Timer won't work because it is not set up to run the repeated code on the Swing event thread and should be avoided with Swing GUI's. Again you should use a Swing Timer since all the code that is called in the Timer's ActionListener is called on the Swing event thread.
On the other hand, if you have a long running task, such as if you wanted to do image analysis or something else that takes a long time to run, then that should be called in a background thread such as via a SwingWorker.
How can I tell ScheduledThreadPoolExecutor(let's call him sht) to execute his task when a button is pressed ?
For example if I have something like this :
sht.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
method1();
method2();
method3();
}
}, 0, 5, TimeUnit.MINUTES);
The methods that are inside sht will execute every 5 minutes but what I want to do is to run them "at now" . I can't just call the methods because some reasons.
I need something like this :
sht.executeNow();
The base execute() method of the Executor interface allows queuing tasks for immediate execution. You should hold a reference to the scheduled Runnable task and submit it for immediate execution on the click of the button.
In case you want to reset the scheduling after the button is clicked, you can do that by removing the previous Runnable task via the remove() method and rescheduling it. The execute() method would not be needed in that case, as you can achieve immediate execution by specifying an initial delay value of 0 in your scheduling method.
Considering your simple use-case, you might want to look at using a Timer instead of ScheduledThreadPoolExecutor, as it provides a much simpler API for what you are attempting. In fact, unless you really need to run these tasks in another Thread, you should use a Handler, which will manage the scheduling and execution of the tasks without needing to start new Threads.
What is the most accurate way to call a function every N milliseconds?
Thread with Thread.sleep
TimerTask
Handler with postDelayed
I modified this example using Thread.sleep and it's not very accurate.
I'm developing a music app that will play sounds at a given BPM. I understand it's impossible to create an entirely accurate metronome and I don't need to - just looking to find the best way to do this.
Thanks
There are some disadvantages of using Timer
It creates only single thread to execute the tasks and if a task
takes too long to run, other tasks suffer.
It does not handle
exceptions thrown by tasks and thread just terminates, which affects
other scheduled tasks and they are never run
ScheduledThreadPoolExecutor deals properly with all these issues and it does not make sense to use Timer.. There are two methods which could be of use in your case.. scheduleAtFixedRate(...) and scheduleWithFixedDelay(..)
class MyTask implements Runnable {
#Override
public void run() {
System.out.println("Hello world");
}
}
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
long period = 100; // the period between successive executions
exec.scheduleAtFixedRate(new MyTask(), 0, period, TimeUnit.MICROSECONDS);
long delay = 100; //the delay between the termination of one execution and the commencement of the next
exec.scheduleWithFixedDelay(new MyTask(), 0, delay, TimeUnit.MICROSECONDS);
On Android you can create Thread with it's own Handler/Message Queue. It's quite accurate. When you see Handler documentation you can see, that it was designed for that.
There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.
They are all the same precision-wise. Java timing precision is subject to the precision and accuracy of system timers and schedulers and is not guaranteed. See Thread.sleep and Object.wait API.
Using TimerTask for the loop action is the better one. Recommend
I have the following situation in a Game i'm working:
class GameLogic implements Runnable
{
State state;
private State changeState()
{
//state changes here (note the `private`)
}
// this ticks at each 0.5 seconds
public void run()
{
//code that changes state
changeState();
}
// this will be called by a external Thread at any moment
public void update(Move move)
{
//code that changes state
applyMove(move);
}
private void applyMove(Move move)
{
//state changes here
//state = ... doesn't matter
}
}
The run method above is scheduled to execute at each 0.5 seconds, using a Timer or a ScheduledExecutorService.
The problem is the update method, will be called by another Thread at any moment. So i ask:
1 - What happens if a use synchronized to protect the state field? The timer will wait? How it will compensate for the 'waiting period'?
2 - Is there a better way of doing this? Maybe storing the moves on some queue?
Thanks!
Both Timer and ScheduledExecutorService can execute tasks at fixed rates or with fixed delays between executions. That means, a scheduled task with fixed rates will compensate the running time (including blocking time) of the execution. A scheduled task with fixed delays will not. See the documentation of the following methods for more information:
Fixed rate: Timer.scheduleAtFixedRate and ScheduledExecutorService.scheduleAtFixedRate
Fixed delay: Timer.schedule and ScheduledExecutorService.scheduleWithFixedDelay
There is always a better way. However, the solution looks fine. And as long as it works for you, go with it.
An additional way to deal with this problem is by having the updates coming in from the updating thread go to a Queue or something similar. This way, on each iteration of the state being adjusted you can grab all of the updates from the queue and apply them in the same thread.
Using this method, there would never be any conflict between the updating thread and the game loop thread.
Personally, I would use a while loop that takes advantage of some regulating mechanism instead of scheduling anything. You can use System.nanoTime() in order to apply your updates using time deltas. This would ensure that the execution of logic is not bound to the machine's performance.
There's a brilliant article on the topic here.
In Java is there a sane way to have a thread/task run continuously and then end after a specified run time (preferably without using several timers)?
For instance, if I have a TimerTask, there doesn't seem to be a way to schedule that task to end after a certain number of milliseconds or at a specific time with the Timer class.
Sure, I can schedule a task to repeat after a number of milliseconds, but what if I want it to end after one iteration? I have to run another timer within this scheduled task? I'm hoping for a more elegant answer than that.
The answer provided in this question could work, but it is definitely not what I had in mind.
Essentially, I'm looking for something similar to the AutoReset property on C#'s System.Timers.Timer class
You can use an ExecutorService, grab the Future you get and .cancel() it after the time you want:
final Future<Whatever> f = executor.submit(...);
TimeUnit.SECONDS.sleep(xxx);
f.cancel(true);
Or you can have two services: one which executes, another which uses a ScheduledExecutorService for the cancellation.
NOTE: TimerTask depends on the system time, use a ScheduledExecutorService instead.
Simply create another thread and have it time it for when it wants the other thread to stop:
class ThreadTimer implements Runnable {
public void run()
{
Thread.sleep(3000);
MainThread.stopThread();
}
}
class MainThread implements Runnable {
public boolean running = true;
public void run()
{
// thread running code
if(!running)
return;
}
public static void stopThread()
{
running = false;
}
}
Where 3000 is the amount of time in milliseconds from when you want the thread to stop.
Since Thread.stop() is deprecated in Java, the next best way is to only execute the thread if a boolean is set to true. When you call to stop the thread, you're setting that boolean to false, making the code in the thread not run.
Because the void run() doesn't repeat itself and only executes once, if you set the boolean to false, it simply returns run() and halts the thread's execution.
If your task is running in a loop, you can check the current time on each iteration, and terminate the loop if enough time has passed.
Or, if your task involves sleeps, you can set a timer on another thread to call Thread.interrupt on the task.
The only other option would be to set a timer on another thread to call Thread.stop. However, Thread.stop has been deprecated, and there's no safe way to stop a general thread in Java.