I have a class that runs for every 10 secs, but when I execute it more than once, multiple timers are started. If one timer is already running, I want the other timer calls to be ignored. I want only one timer to be running at a given point of time. Please help.
My code:
import java.util.Timer;
import java.util.TimerTask;
public class Test1 extends TimerTask{
#Override
public void run() {
System.out.println("In run method");
}
public static void main(String args[]) {
System.out.println("In main method");
Timer timer= new Timer();
timer.schedule(new Test1(), 10000,10000);
}
}
I want the 1st timer to be running always. Other timers calls should not be triggered at all.
Try with Singleton patten that allows only single instance of the class.
Sample code:
public class Test extends TimerTask {
private static Test instance = new Test();
private Test() {}
public static Test getInstance() {
return instance;
}
#Override
public void run() {
System.out.println("In run method");
}
}
Now if you try to start another Task on the same instance it will result in below exception:
java.lang.IllegalStateException: Task already scheduled or cancelled
at java.util.Timer.sched(Unknown Source)
at java.util.Timer.schedule(Unknown Source)
Why don't you try something like setting a bool true if you start a timer and only let the other Timers start if it's true or false, depends on how you set them
sth like:
boolean checkTimer = false;
//Start a Timer and set checkTimer = true
if(checkTimer == true)
{
//Start your other timers here
}
else
{
//Write message that timer is already running
}
Related
I'm coding an assignment and currently everything's working fine. I'm not going to post the whole thing but the essential classes being called and referenced.
Basically, my problem is that I have a GameTimer class to start a Timer in my Game:
public class GameTimer {
GameViewController gvc = GameFrame.gameViewController;
public static boolean isRunning = false;
public int seconds = 0;
public Timer timer = null;
public TimerTask task = null;
public GameTimer () {
timer = new Timer();
}
public void start() {
task = new TimerTask() {
#Override
public void run() {
gvc.updateTime(seconds);
seconds++;
}
};
timer.scheduleAtFixedRate(task, 1000, 1000);
System.out.println("Task was started");
isRunning = true;
}
public void stop() {
task.cancel();
timer.cancel();
timer.purge();
isRunning = false;
}
public void restart() {
stop();
start();
}
}
And basically I have different modes that extends a GameModel and references my GameTimer instance in my GameModel class :
public class GameModel {
public GameTimer game_timer = new GameTimer();
//... Rest of instances and classes
}
public class Mode1 extends GameModel {
public Mode1() {
if(!gamer_timer.isRunning)
game_timer.start();
else
game_timer.restart();
}
//.....Rest of methods
}
public class Mode2 extends GameModel {
public Mode2() {
if(!gamer_timer.isRunning)
game_timer.start();
else
game_timer.restart();
}
//.....Rest of methods
}
Basically, my game is a GUI and i have a drop-down box from which I select my modes. My game instantly loads Mode1 when it runs, but when I choose Mode2, it returns a NullPointerException on my
task.cancel();
I've read on some other posts that you have to cancel the TimerTask before the Timer, but whether I put timer cancel before the task cancel
task.cancel
timer.cancel()
it still gives me the same NullPointerException
Here's the error:
Exception in thread "AWT-EventQueue-0" Mode2
java.lang.NullPointerException
at GameTimer.stop(GameTimer.java:32) // task.cancel()
at GameTimer.restart(GameTimer.java:39)
at Mode2.<init>(Mode2.java:15)
Can you help me just figure out why is the task not cancelling.
Why is isRunning static?
Mode1 sets it to true. Mode2 is created and it should read false for isRunning but instead it reads true (class variable = only one used) so instead of calling start( ) it calls restart( ) and gets the NPE because it was never started and so can't be stopped.
I didn't clearly read your explanation line by line but what I can say by seeing your code is that,
Here inside restart() method you are calling stop() first and start() second
public void restart() {
stop();
start();
}
Inside the start() method you are initializing your task object like here
public void start() {
task = new TimerTask()
But as per your code this seems second priority of your code, stop() is called at first, But at that time task was not initialized. I suggest you to rearrange this as per your needs and initialize task anywhere you feel comfortable but be sure you initialized before using.
Thanks for your help. I found the solution. Mode1 is being initialized as I run the game
new Mode1 ();
and the same Mode2. It would initilized when I choose Mode2 in my game. However, because I'm reinitializing the same gameModel over my program, the isRunning would always be false at first because in my GameModel, you see me create a new instance of my GameTimer everytime. So basically, the state of the timer would never be set to true.
I've found the problem to my code but I have figured a solution yet so I will post the solution as soon I am done with it. Thank you for helping
I have a game where I am scheduling a timer. I have this CoresManager file:
package com.rs.cores;
import java.util.Timer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
public final class CoresManager {
protected static volatile boolean shutdown;
public static WorldThread worldThread;
public static ExecutorService serverWorkerChannelExecutor;
public static ExecutorService serverBossChannelExecutor;
public static Timer fastExecutor;
public static ScheduledExecutorService slowExecutor;
public static int serverWorkersCount;
public static void init() {
worldThread = new WorldThread();
int availableProcessors = Runtime.getRuntime().availableProcessors();
serverWorkersCount = availableProcessors >= 6 ? availableProcessors - (availableProcessors >= 12 ? 7 : 5) : 1;
serverWorkerChannelExecutor = availableProcessors >= 6 ? Executors
.newFixedThreadPool(availableProcessors - (availableProcessors >= 12 ? 7 : 5),
new DecoderThreadFactory()) : Executors.newSingleThreadExecutor(new DecoderThreadFactory());
serverBossChannelExecutor = Executors
.newSingleThreadExecutor(new DecoderThreadFactory());
fastExecutor = new Timer("Fast Executor");
slowExecutor = availableProcessors >= 6 ? Executors.newScheduledThreadPool(availableProcessors >= 12 ? 4 : 2,
new SlowThreadFactory()) : Executors
.newSingleThreadScheduledExecutor(new SlowThreadFactory());
worldThread.start();
}
public static void shutdown() {
serverWorkerChannelExecutor.shutdown();
serverBossChannelExecutor.shutdown();
fastExecutor.cancel();
slowExecutor.shutdown();
shutdown = true;
}
private CoresManager() {
}
}
I am using this inside the game:
private void startTimer() {
CoresManager.fastExecutor.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
if (timer == 0 || timer < 1) {
player.sm("Your timer has ended! The NPCs will no longer spawn.");
timer = 0;
this.cancel();
exitInstance();
return;
}
timer--;
timerchecker = true;
seconds = timer % 60;
player.setTimer(timer);
minutes = TimeUnit.SECONDS.toMinutes(timer);
}
}, 0, 1000);
}
The CoresManager Timer stops running if the player logs out AND the server gets rebooted. To make it run again, I added a code to make it do startTimer() again once you log back in. However, since the timer still runs if the server didn't log out, the timer starts running twice. The Timer starts getting subtracted by 2, or more, depending on how many times you log out and in. I figure that it would fix if there was a code to determine if the timer is already running. Is there a way to do this? Please help!
I don't see anything in the documentation that provides for checking the status on a TimerTask object (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/TimerTask.html) so one option would be to extend TimerTask and create your own class. Instead of using an anonymous TimerTask, you could create something along the lines of:
public class CoresTimerTask extends TimerTask {
private boolean hasStarted = false;
#Overrides
public void run() {
this.hasStarted = true;
//rest of run logic here...
}
public boolean hasRunStarted() {
return this.hasStarted;
}
}
and just maintain a reference to this CoresTimerTask object, which you then pass into startTimer(). You can then later check this object via hasRunStarted.
public long scheduledExecutionTime()
Returns the scheduled execution time of the most recent actual execution of this task. (If this method is invoked while task execution is in progress, the return value is the scheduled execution time of the ongoing task The return value is undefined if the task has yet to commence its first execution.
This method is typically not used in conjunction with fixed-delay execution repeating tasks, as their scheduled execution times are allowed to drift over time, and so are not terribly significant.
first thing periodically running tasks need set/reset state flag
second (when i look at examples) it is better to seal this type of class
but if someone insist to have such methods
public abstract class NonInterruptableTask extends TimerTask {
protected boolean isDone = false;
public boolean isDone() {return isDone;}
protected abstract void doTaskWork();
#Override
public void run() {
isDone = false;
doTaskWork();
isDone = true;
}
}
usage:
TimerTask myTask = new NonInterruptableTask() {
#Override
public void doTaskWork() {
//job here
}
};
you could also declare a boolean state called like "timerstate" or whatever and make it by default to be false. whenever you start a timer you could change this boolean to true and you'd be able to keep track of the timer.
public boolean timerstate;
public Timer t1;
// some code goes here to do whatever you want
if(timerstate == true) {
t1.cancel();
t1.purge();
t1 = new Timer();
} else{
t1.schedule(new TimerTask() {
#Override
public void run() {
timerstate = true;
//rest of code for the timer goes here
}
}
}
I've a Java project which is main create an instance of a class (ThreadClient) that extends Thread. I would need that ThreadClient.run starts 2 timers to run periodically 2 methods of the ThreadClient class.
The examples I found in internet just show that the timer can start the run method of an instance of a classe that exteds the Thread class.
I woundln't need to create a new class, just to run 2 methods of the same class that creates the timers.
Something like C# does:
public class ThreadClient
{
private Timer _timer;
public ThreadClient() {
Start();
}
private void Start()
{
_timer = new Timer(3000); // Set up the timer for 3 seconds
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Enabled = true; // Enable it
}
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
// do something
}
}
Method _timer_Elapsed belongs to the class that creates the timer.
Thanks in advance,
Samuel
That's how I finally reached my goal:
// Timer to process sales
TimerTask ttProcessSales = new TimerTask() {
#Override
public void run() {
processSales();
}
};
Timer tProcessSales = new Timer();
tProcessSales.schedule(ttProcessSales, 0, this._processTaskTimeInterval);
// Timer to process tasks
TimerTask ttProcessTask = new TimerTask() {
#Override
public void run() {
processTasks();
}
};
Timer tProcessTasks = new Timer();
tProcessTasks.schedule(ttProcessTask, 0, this._processTaskTimeInterval);
In this way I can run 2 methods of the class using timers without create new class for every method I needed to execute.
I need a simple way to call a function every 60 minutes. How can I do this? I'm making a MineCraft bukkit plugin, and this is what I have:
package com.webs.playsoulcraft.plazmotech.java.MineRegen;
import java.util.logging.Logger;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.plugin.java.JavaPlugin;
public class Main extends JavaPlugin{
public final Logger log = Logger.getLogger("Minecraft");
#Override
public void onEnable() {
this.log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
this.log.info("Plaz's Mine Regen is now enabled!");
this.log.info("Copyright 2012 Plazmotech Co. All rights reserved.");
this.log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
#Override
public void onDisable() {
this.log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
this.log.info("Plaz's Mine Regen is now disabled!");
this.log.info("Copyright 2012 Plazmotech Co. All rights reserved.");
this.log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
public void onPlayerInteract(PlayerInteractEvent event) {
final Action action = event.getAction();
if (action == Action.LEFT_CLICK_BLOCK) {
Location l1 = event.getClickedBlock().getLocation();
} else if (action == Action.RIGHT_CLICK_BLOCK) {
Location l2 = event.getClickedBlock().getLocation();
}
}
}
I need to run a function I will implement every hour, how? Remember: The function will use l1, and l2. Also, how can I loop this to get every block inbetween?
Create a Timer object and give it a TimerTask that performs the code you'd like to perform.
Timer timer = new Timer ();
TimerTask hourlyTask = new TimerTask () {
#Override
public void run () {
// your code here...
}
};
// schedule the task to run starting now and then every hour...
timer.schedule (hourlyTask, 0l, 1000*60*60);
If you declare hourlyTask within your onPlayerInteract function, then you can access l1 and l2. To make that compile, you will need to mark both of them as final.
The advantage of using a Timer object is that it can handle multiple TimerTask objects, each with their own timing, delay, etc. You can also start and stop the timers as long as you hold on to the Timer object by declaring it as a class variable or something.
I don't know how to get every block in between.
Create a thread that will run forever and wakes up every hour to execute your data.
Thread t = new Thread() {
#Override
public void run() {
while(true) {
try {
Thread.sleep(1000*60*60);
//your code here...
} catch (InterruptedException ie) {
}
}
}
};
t.start();
You must use Bukkit Scheduler:
public void Method(){
this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
#Override
public void run() {
// Your code goes here
Method();
}
}, time * 20L );
}
You must create a method with this and there you must call the same method.
The simplest way (in my opinion) is use Thread (the above comment has mention about it).
You can also use Timer in javax.swing.Timer
But i think - as 101100 said - you can use TimerTask. You can check this link (from IBM)
I have a question about the behaviour of Timer class in Java.
This is the code: http://pastebin.com/mqcL9b1n
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.foo();
m = null;
}
public void foo() {
Timer t = new Timer();
t.schedule(new SysPrint(), 200);
}
}
class SysPrint extends TimerTask {
public void run() {
System.out.println("Yes!");
}
}
What happens is that if you run that program, it will print "Yes!" and it's not gonna do anything else (the program doesn't end).
The Java documentation says:
After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection).
As I see this thing, the "last live reference" to the Timer object is gone after the 'foo()' functions ends. And the only task scheduled was the "Yes!" task that was executed, so I guess that after the process printed "Yes!", the Timer object should end and the process should terminate.
What happened here?
Java is not exiting because your thread running the Timer is still kicking around. You have to mark that thread as being a daemon thread before Java will exit. You probably don't have access to the thread itself so unless Timer has a method to mark it so you'll have a hard time doing that. You'll need to manually stop it in a finally clause.
try {
timer = new Timer();
timer.schedule( new SysPrint(), 200 );
} finally {
timer.cancel();
}
I believe the code below should do the trick.
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.foo();
m = null;
}
public void foo() {
Timer t = new Timer();
t.schedule(new SysPrint(), 200);
}
}
class SysPrint extends TimerTask {
SysPrint(Timer timer) {
this.timer = timer;
}
public void run() {
System.out.println("Yes!");
timer.cancel();
}
private Timer timer;
}
When you create a Timer object. A TimerThread is created. And it the internal thread to run your task. You can view the method run() of TimerThread. You can see it has a while loop.
private void mainLoop() {
while (true) {....
The TimerThread not set to a daemon, so the main method execute completely, the jvm not exists.
That why your program is always running and don't stop.