Java: run a method periodcally using timer - java

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.

Related

Listener in multithreading only called when passed anonymously, not when declared as member

Edit
I figured it out:
The order in which I initialized the Service members was important! Other members (not shown in my examples) reference the Timer in Runnables by calling the Service getter getTimer() (not shown either). In this getter the listener is registered, but not initialized yet, because it was declared/initialized after the other members, not before them. Sigh...
I have a class Service and an inner class Timer which runs in a separate thread. This timer accepts a tick listener, which is called at fixed intervals when the timer is running.
The gist of it is this:
public class Service {
private Timer timer;
Service() {
// more to follow in code snippets below where I demonstrate the issue I am facing
}
private static class Timer
implements Runnable {
private interface TickListener {
void onTick(Timer timer);
}
private TickListener tickListener;
public void setTickListener(TickListener tickListener) {
this.tickListener = tickListener;
}
public void start() {
new Thread(this).start();
}
#Override
public void run() {
while(keepThreadRunningCondition) {
if(tickListener != null) {
// to verify that Timer is actually running
// and tickListener is not null
// I actually log here
// and the log appears just fine in all cases
tickListener.onTick(this);
}
}
}
}
}
Now, when I register the tick listener anonymously, like so:
class Service {
private Timer timer;
Service() {
timer = new Timer();
timer.setTickListener(new Timer.TickListener() {
#Override
void onTick(Timer timer) {
// this gets called perfectly fine
}
});
}
}
...the listener gets called just fine, when the timer is started.
However, when I register the tick listener as a member of my Service class, like so (I've tried a couple of different permutations of public, final, volatile, etc. as well):
class Service {
private Timer timer;
private Timer.TickListener timerTickListener = new Timer.TickListener() {
#Override
void onTick(Timer timer) {
// this will NOT get called
}
};
Service() {
timer = new Timer();
timer.setTickListener(timerTickListener);
}
}
...the listener does not get called, when the timer is started.
I suspect this issue is related to multithreading, because similar setups work just fine when not spanning different threads, but I'm not well-versed enough in multithreading to understand exactly why this is not working.
Can you shed a light on this issue?
Does it have something to do with accessing objects by reference across different threads, perhaps? Or is it something different?
You claimed that upon registering TickListener as Service's member variable, onTicket will not get called.
This was not correct. I ran the code myself and it got called.
Here is my code,
package com.company;
public class Service {
private Timer timer;
Timer.TickListener tickListener = new Timer.TickListener() {
#Override
public void onTick(Timer timer) {
// this gets called perfectly fine
System.out.println(42);
}
};
Service() {
// more to follow in code snippets below where I demonstrate the issue I am facing
timer = new Timer();
timer.setTickListener(tickListener);
}
private static class Timer
implements Runnable {
private interface TickListener {
void onTick(Timer timer);
}
private TickListener tickListener;
public void setTickListener(TickListener tickListener) {
this.tickListener = tickListener;
}
public void start() {
new Thread(this).start();
}
#Override
public void run() {
while(true) {
if(tickListener != null) {
// to verify that Timer is actually running
// and tickListener is not null
// I actually log here
// and the log appears just fine in all cases
tickListener.onTick(this);
}
try{
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public void foo() {
timer.start();
}
public static void main(String[] args) {
Service service = new Service();
service.foo();
}
}

Why does my TimerTask.cancel() returns an NPE ? (JAVA)

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

TimerTask class has to run only once in java

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
}

Java Object init() and the Timer class

I was just writing some code, and it occurred to me. I am creating a Timer object and scheduling a repeating task via timer.scheduleAtFixedRate(...).
public class MyClass {
..
public MyClass() {
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
doStuffEachSecond();
}
}, (long)0, (long)1000);
// more stuff
}
Now, doStuffEachSecond() is an instance method on MyClass. Since my initial delay is zero,
and there is more stuff that goes on in the constructor after my Timer is set up, how do I know that the first invocation of my timer won't occur before object initialization is complete? Or might that potentially be the case (which would of course not be good)?
For now my solution is that my timer's setup is the final step of the constructor, but that seems iffy at best. Any wisdom regarding this issue?
If you really want to insure that MyClass is fully initialized before the timer starts, you can do the initialization and the timer start in two steps:
final MyClass myMlass = new MyClass();
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
myclass.doStuffEachSecond();
}
}, 0L, 1000L);
Edit
After thinking about it, putting the above in a static factory method would be by far the best solution:
public class MyClass {
private MyClass() { /* do stuff */ }
public static MyClass createNew() {
MyClass myClass = new MyClass();
myClass.startRunning();
}
private void startRunning() {
new Timer(true).scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
doStuffEachSecond();
}
}, 0L, 1000L);
}
}
This does everything you want. The only way to create a new MyClass is via its factory method, and whenever a new one is created its timer is started after it's initialized.
I would use something similar to what threads in Java do. Have a constructor, then call a method like start to begin the timer.
Resolving race issues here seems a bit overkill when you can just construct the object then immediately begin timing. If you have a Factory to create the objects this could be part of the construction process.
I would separate scheduling from object creation. You are right that it smells.
public class MyClass {
...
public MyClass() {
...
}
public static void start(final MyClass mc) {
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
mc.doStuffEachSecond();
}
}, (long)0, (long)1000);
}
}
Do this instead: Call the method in the class you are using the MyClass object.
public class MyClass {
public MyClass() {
// more stuff
}
private void startTimer(){
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
doStuffEachSecond();
}
}, (long)0, (long)1000);
}
public class usingClass{
public static void main(String args[]){
MyClass mc=new MyClass();
mc.startTimer();
}
}

TimerTask keeps running

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.

Categories