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();
}
}
Related
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();
}
}
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'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.
Being a fan of the Pomodoro technique I'm making myself a countdown timer to keep me on task with my homework. This particular project, however, is NOT homework. :)
Stack has a LOT of questions about using timers to control delays before user input and the like, but not a lot on standalone timers. I've run across this code from a friend, and have studied the class on Java Documentation.
public class Stopwatch {
static int interval;
static Timer timer;
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.print("Input seconds => : ");
String secs = sc.nextLine();
int delay = 1000;
int period = 1000;
timer = new Timer();
interval = Integer.parseInt( secs );
System.out.println(secs);
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
System.out.println(setInterval());
}
}, delay, period);
}
private static final int setInterval()
{
if( interval== 1) timer.cancel();
return --interval;
}
}
There is some syntax that's not clear to me. Consider:
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
System.out.println(setInterval());
}
}, delay, period);
I'm not understanding how the parentheses and braces work. At first glance, given the usage of scheduleAtFixedRate(TimerTask task, long delay, long period) I can see the delay and period parameters, but not an open paren preceding first parameter.
Is my first parameter actually this whole block of code? I would expect the whole block to be surrounded by parentheses...but it's not. Is this a common syntax in java? I've never run across it before.
new TimerTask()
{
public void run()
{
System.out.println(setInterval());
}
}
I just want to clarify that I understand it before I start mucking about with changes.
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
System.out.println(setInterval());
}
}, delay, period);
That code is equivalent to this refactoring, where the new TimerTask is assigned to a local variable.
TimerTask task = new TimerTask()
{
public void run()
{
System.out.println(setInterval());
}
};
timer.scheduleAtFixedRate(task, delay, period);
Of course the weird part has just moved upwards a bit. What is this new TimerTask stuff, exactly?
Java has special syntax for defining anonymous inner classes. Anonymous classes are a syntactical convenience. Instead of defining a sub-class of TimerTask elsewhere you can define it and its run() method right at the point of usage.
The code above is equivalent to the following, with the anonymous TimerTask sub-class turned into an explicit named sub-class.
class MyTimerTask extends TimerTask
{
public void run()
{
System.out.println(setInterval());
}
}
TimerTask task = new MyTimerTask();
timer.scheduleAtFixedRate(task, delay, period);
You are correct, the first parameter is the entire code block:
new TimerTask()
{
public void run()
{
System.out.println(setInterval());
}
}
These declarations are called Anonymous classes and are explained in more detail in the Java Tutorials.
It is a anonymous inner class. You need to study inner classes for understanding this. Generally such classes are used when you do not need the class to be used else where in your code. You cannot use it else where just because you dont have reference pointing to it.
You can also replace the above code as follows :
class MyTimerTask extends TimerTask {
#Override
public void run() {
// Timer task code goes here.
System.out.println(setInterval());
}
}
MyTimerTask timerTask = new MyTimerTask();
timer.scheduleAtFixedRate(timerTask, delay, period);
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.