I was looking for a Java timer sample and found the code below at
http://www.javaprogrammingforums.com/java-se-api-tutorials/883-how-use-timer-java.html
But if you run the sample, although it does print Timer stops now... it does not return to the command prompt. This is at least what is happening on my Windows XP machine using cmd.exe.
Why does it not return control to the prompt in this case?
import java.util.Timer;
import java.util.TimerTask;
public class TimerSample {
public static void main(String[] args) {
//1- Taking an instance of Timer class.
Timer timer = new Timer("Printer");
//2- Taking an instance of class contains your repeated method.
MyTask t = new MyTask();
//TimerTask is a class implements Runnable interface so
//You have to override run method with your certain code black
//Second Parameter is the specified the Starting Time for your timer in
//MilliSeconds or Date
//Third Parameter is the specified the Period between consecutive
//calling for the method.
timer.schedule(t, 0, 2000);
}
}
class MyTask extends TimerTask {
//times member represent calling times.
private int times = 0;
public void run() {
times++;
if (times <= 5) {
System.out.println("I'm alive...");
} else {
System.out.println("Timer stops now...");
//Stop Timer.
this.cancel();
}
}
}
It does not return to your command prompt because it is not expected to do so.
Timer creates single non-deamon thread to run all tasks. It does not terminate the thread unless you ask it. When you execture task.cancel() method you just cancel the current task, not the whole timer which is still alive and is ready to do something else.
To terminate timer you should call its stop() method, i.e. timer.stop();
In a real program you would keep a copy of the timer object and when eg program is to be closed down do a timer.cancel().
For this simple example, I added the code below after timer.schedule(t, 0, 2000);
try {
Thread.sleep(20000);
} catch(InterruptedException ex) {
System.out.println("caught " + ex.getMessage());
}
timer.cancel();
}
You need to explicitly terminate the Timer using timer.cancel(), e.g.:
class MyTask extends TimerTask {
private int times = 0;
private Timer timer;
public MyTask(Timer timer) {
this.timer = timer;
}
public void run() {
times++;
if (times <= 5) {
System.out.println("I'm alive...");
} else {
System.out.println("Timer stops now...");
//Stop Timer.
this.cancel();
this.timer.cancel();
}
}
}
Related
I have got the basics of how Timer and TimerTask work in Java. I have a situation where I need to spawn a task that will run periodically at fixed intervals to retrieve some data from database. And it needs to be terminated based on the value of the retrieved data (the data itself is being updated by other processes)
Here is what I came up with so far.
public class MyTimerTask extends TimerTask {
private int count = 0;
#Override
public void run() {
count++;
System.out.println(" Print a line" + new java.util.Date() + count);
}
public int getCount() {
return count;
}
}
And a class with a main method like so. For now I have trivially used a 15 second sleep to control how long the timerTask runs.
public class ClassWithMain {
public static void main(String[] args) {
System.out.println("Main started at " + new java.util.Date());
MyTimerTask timerTask = new MyTimerTask();
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(timerTask, 0, 5*10*100);
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main done"+ new java.util.Date());
}
The MyTimerTask class will become more complex with the database service calls and so on.
What I want to be able to do is, in the main class, interrogate a value returned by timerTask to dictate when to invoke timer.cancel() and terminate the process. Right now if I try to use the count property of MyTimerTask it doesn't work. So when I tried adding these lines in ClassWithMain
if (timerTask.getCount() == 5){
timer.cancel();
}
it didn't stop the process.
So I'd like any direction on how I might be able to accomplish what I'm trying to do.
private volatile int count = 0; It is better to use 'volatile'.
try this in ClassWithMain:
for(;;) {
if (timerTask.getCount() == 5) {
timer.cancel();
break;
} else{
Thread.yield();
}
}
I need a loop with delay (like a timer) but have problems with the end of it, this is my code:
while(true) {
if (someValue == 10) {
break;
}
//Wait two seconds. <-----
}
System.out.println("While Ended.");
This works fine, but need to be repeated every 2 seconds. I tried with Timer but the "While Ended." message is shown before of the timer end. How can i solve this problem?
I need that this process not freeze the thread. (like while loop).
Precision is not necessary.
You can put Thread.sleep in a while-loop to sleep for a number of seconds. This solution has problems, e.g. it blocks the thread, breaks on interrupts, etc.
Better is to use a ScheduledThreadPoolExecutor and use the schedule method to schedule the task to run every so many seconds. This is correct but you should have some knowledge of how multithreaded programs work or you'll make mistakes and create subtle bugs.
When you need something like a timer than you could use a timer:
import java.util.Timer;
import java.util.TimerTask;
public class TTimer extends TimerTask {
private static Timer timer;
#Override
public void run() {
System.out.println("timer");
}
public void stop() {
timer.cancel();
timer.purge();
this.cancel();
}
public TTimer( long interval) {
timer = new Timer(true);
timer.scheduleAtFixedRate(this, 0, interval);
}
public static void main(String[] args) {
TTimer t = new TTimer(2000);
while( true ) {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
}
}
}
}
Place your code in the run() method, check your condition (somevalue == 10) and call the stop method to shut the timer down.
I have an event listener which detects when the mouse is being moved in a certain pane of my program. From this, I want to be able to perform some action if the mouse stays idle for too long.
I have looked all over earlier today, to try and find an explanation and example which details how to start, stop/cancel and reset a timer but have been bombarded with different ways to try and do this, which has left me quite confused.
I'm following a timer example from here and implementing for my own situation
When this code below is run, it will output "A" every time the mouse stops. This is incorrect, as if I stop the mouse, move it quickly then stop it again, 2 sets of "A" are produced.
This carries on for however many times the stop is produced.
I believe I am missing a 'reset timer' function that will called when the mouse changes to a moving state.
How can I implement this?/Is that even the problem?
public class SomeClass{
//...some fancy code...
if (! isNowMoving) {
System.out.println("Mouse stopped!");
//Start Timer
new PrintingA(5);
} else if (isNowMoving){
System.out.println("MouseMoving");
//cancel timer & reset ready to start
}
public class PrintingA {
Timer timer;
public PrintingA(int seconds) {
timer = new Timer();
timer.schedule(new PrintingTask(), seconds * 1000);
}
class PrintingTask extends TimerTask{
#Override
public void run() {
System.out.println("A");
timer.cancel();
}
}
}
}
I'm not sure this can be useful for your requirement, Timer is a facility for threads to schedule tasks for future execution in a background thread. Tasks may be scheduled for one-time execution, or for repeated execution at regular intervals. Read java document : java.util.Timer
I perfer to have a thread for IdleMonitor and use Apache Stopwatch to monitor idle time.
import org.apache.commons.lang3.time.StopWatch;
public class IdleMonitor implements Runnable {
StopWatch stopWatch;
private final Object monitorObj = new Object();
private boolean isActive;
private long waitTime = 6000; //in milliseconds, put appropriate time to wait
public IdleMonitor() {
isActive = true;
stopWatch = new StopWatch();
}
public void reset() { // call this during MouseMoving event
synchronized (monitorObj) {
stopWatch.reset();
monitorObj.notify();
}
}
public void finish() { // finish idle mointor operation once your operation ends, this will stop the thread
isActive = false;
reset();
}
public void start() { // start monitoring
Thread t = new Thread(IdleMonitor.this);
t.start();
}
#Override
public void run() {
synchronized (monitorObj) {
stopWatch.start();
while (isActive) {
try {
monitorObj.wait(waitTime);
} catch (InterruptedException ex) {
}
long idleTime = stopWatch.getTime();
System.out.println("Idle time " + idleTime);
// do something if idle time beyond your expected idle time.
// you could set isActive=false; if you want to stop monitoring
}
}
}
}
}
I've got a program that controls an electronic component. My problem is the part with the countdown. Practically if I call the class CountDown from the main method, it won't return to the main. The program must be always active and it reads the first value in the main for call and start the countdown.
This is the code:
public class CountDown
{
public static int a;
public static Timer timer;
public CountDown()
{
timer = new Timer();
timer.schedule(new DisplayCountdown(), 0, 1000);
}
class DisplayCountdown extends TimerTask
{
int seconds = 15;
public void run()
{
if (seconds > 0)
{
System.out.println(seconds + " seconds remaining");
if(READING BY ELECTRONIC COMPONENT == 1)
{
seconds=15;
} else {
seconds--;
}
} else {
System.out.println("Countdown finished");
CountDown.a=0;
}
}
}
public static void main(String args[])
{
CountDown.a = 0;
while(true)
{
if(READING ELECTRONIC COMPONENT == 1)
{
if (CountDown.a==0)
{
CountDown.a = 1;
new CountDown();
}
}
}
}
I've checked to make sure my suspicions are correct. It's not that your new Countdown() isn't returning to the main method, it's that it returns immediately. What you want is likely to do some kind of waiting in the while(true) loop and checking whether or not the countdown is completed. Something along the lines of:
CountDown countDown = null;
while(true)
{
if (countDown == null || getReading() == 1)
{
if (CountDown.a == 0)
{
CountDown.a = 1;
countDown = new CountDown();
}
}
while (countDown.isRunning())
{
try
{
Thread.sleep(countDown.getRemainingSeconds() * 1000);
}
catch (InterruptedException ex)
{
// Ignore.
}
}
}
Obviously you'll need to implement the isRunning and getRemainingSeconds methods (you could always sleep for a set amount rather than trying to wait exactly the right amount of time if you want).
I'd also recommend trying to make this class better suited for re-use by avoiding the static variables a and timer (use private variables and setters/initialise them in the constructor instead).
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.