I wanted to write a timer in java.which will do the following:
when program starts,start the timer1 which will stop after 45 mins, at the same time start the second timer, which will stop after 15 mins. at this time the first timer will starts again, and repeat the above loop until the program exits
first timer : 45 min (the time I can use computer)
second timer: 15 min (the pause time)
first timer : 45 min (the time I can use computer)
second timer: 15 min (the pause time)
first timer : 45 min (the time I can use computer)
second timer: 15 min (the pause time)
I dont know how to use the thread and timer (utils,swing) so I tried to use while(true) but the cpu goes up.
here is my current code
static int getMinute(){
Calendar cal=Calendar.getInstance();
int minute=cal.getTime().getMinutes();
return minute;
}
public static Runnable clockf(){
if (endTime>=60){
endTime=endTime-60;}
System.out.println(startTime);
System.out.println(currentTime);
System.out.println(endTime);
if(currentTime==endTime){
pauseStart=getMinute();
currentTime=getMinute();
pauseEnd=pauseStart+15;
if(currentTime==pauseEnd){
pauseStart=0;
pauseEnd=0;
startTime=getMinute();
currentTime=getMinute();
endTime=startTime+45;
}
}
else{
update();
}
return null;
}
private static void update() {
currentTime=getMinute();
System.out.println(currentTime);
}
public static void main(String[] args) {
startTime=getMinute();
currentTime=getMinute();
endTime=startTime+45;
Thread t=new Thread(clockf());
t.setDaemon(true);
t.start();
try {
Thread.currentThread().sleep(1000);//60000
} catch (InterruptedException e) {
System.err.println(e);
}
}
but it isnt good. are there any way to make the clockf method run only once / min ?
or any other way to make that timer runs ?
Even though I did not fully understand what you're trying to do
Timer and TimerTask should do that for you.
Following code has to improved a bit to be runnable, but hopefully shows the principle:
long minute = 1000*60;
Timer timer1 = new Timer();
long delay1 = 45*minute;
Timer timer2 = new Timer();
long delay2 = 15*minute;
TimerTask tt1;
TimerTask tt2;
...
tt1 = new TimerTask()
{
public void run()
{
//do something and:
timer2.schedule(tt2, delay2);
}
};
tt2 = new TimerTask()
{
public void run()
{
//do something and:
timer1.schedule(tt1, delay1);
}
};
timer1.schedule(tt1, delay1);
The fastest code to write and easiest to maintain is something that you don't write at all.
I'd look into a timer and job scheduler like Quartz to see if it could help you.
There are some major problems in your code and your understanding of the Thread-classes. What I assume you are trying to do, is to define a Runnable that you pass to the thread. What you actually do, however, is execute the clockf() function as a paramter to the constructor of Thread.
If you do need a timer, look at the Java-Timer class:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Timer.html
If you need to write it yourself, study the Thread class and especially the semantics of sleep and wait.
I solve the problem with Timer
Now I can use the computer 45 min, then pause 15 min
Many thank for all of your help, and special for kai1968 ^^ and this site http://www.roseindia.net/java/example/java/util/CertainAndRepeatTime.shtml
and can anyone tell me what static means? I dont really know why static should be there.
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Timer;
import java.util.TimerTask;
public class clock2 {
static long minute = 1000*1;//60;
static Timer timer1 = new Timer();
static long delay1 = 60*minute;
static Timer timer2 = new Timer();
static long delay2 = 45*minute;
static TimerTask tt1;
static TimerTask tt2;
static String s;
static String getSecond(){
Calendar calendar = new GregorianCalendar();
int second = calendar.get(Calendar.SECOND);
s=Integer.toString(second);
return s;
}
public static void timer(){
tt1=new TimerTask(){
public void run(){
getSecond();
System.out.println(s+"Begin");
}
};
tt2=new TimerTask(){
public void run(){
getSecond();
System.err.println(s+"Stop");
}
};
timer1.schedule(tt1 ,0,delay1);
timer2.schedule(tt2 ,delay2,delay1);
}
public static void main(String[] args) {
timer();
}
}
Related
I have a thread which is in charge of doing some processes. I want make it so that these processing would be done every 3 seconds. I've used the code below but when the thread starts, nothing happens.
I assumed that when I define a task for my timer it automatically execute the ScheduledTask within time interval but it doesn't do anything at all.
What am I missing?
class temperatureUp extends Thread
{
#Override
public void run()
{
TimerTask increaseTemperature = new TimerTask(){
public void run() {
try {
//do the processing
} catch (InterruptedException ex) {}
}
};
Timer increaserTimer = new Timer("MyTimer");
increaserTimer.schedule(increaseTemperature, 3000);
}
};
A few errors in your code snippet:
You extend the Thread class, which is not really good practice
You have a Timer within a Thread? That doesnt make sense as the a Timer runs on its own Thread.
You should rather (when/where necessary), implement a Runnable see here for a short example, however I cannot see the need for both a Thread and Timer in the snippet you gave.
Please see the below example of a working Timer which will simply increment the counter by one each time it is called (every 3seconds):
import java.util.Timer;
import java.util.TimerTask;
public class Test {
static int counter = 0;
public static void main(String[] args) {
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
System.out.println("TimerTask executing counter is: " + counter);
counter++;//increments the counter
}
};
Timer timer = new Timer("MyTimer");//create a new Timer
timer.scheduleAtFixedRate(timerTask, 30, 3000);//this line starts the timer at the same time its executed
}
}
Addendum:
I did a short example of incorporating a Thread into the mix. So now the TimerTask will merely increment counter by 1 every 3 seconds, and the Thread will display counters value sleeping for 1 seconds every time it checks counter (it will terminate itself and the timer after counter==3):
import java.util.Timer;
import java.util.TimerTask;
public class Test {
static int counter = 0;
static Timer timer;
public static void main(String[] args) {
//create timer task to increment counter
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
// System.out.println("TimerTask executing counter is: " + counter);
counter++;
}
};
//create thread to print counter value
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
System.out.println("Thread reading counter is: " + counter);
if (counter == 3) {
System.out.println("Counter has reached 3 now will terminate");
timer.cancel();//end the timer
break;//end this loop
}
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
});
timer = new Timer("MyTimer");//create a new timer
timer.scheduleAtFixedRate(timerTask, 30, 3000);//start timer in 30ms to increment counter
t.start();//start thread to display counter
}
}
import java.util.Timer;
import java.util.TimerTask;
public class ThreadTimer extends TimerTask{
static int counter = 0;
public static void main(String [] args) {
Timer timer = new Timer("MyTimer");
timer.scheduleAtFixedRate(new ThreadTimer(), 30, 3000);
}
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("TimerTask executing counter is: " + counter);
counter++;
}
}
In order to do something every three seconds you should use scheduleAtFixedRate (see javadoc).
However your code really does nothing because you create a thread in which you start a timer just before the thread's run stops (there is nothing more to do). When the timer (which is a single shoot one) triggers, there is no thread to interrupt (run finished before).
class temperatureUp extends Thread
{
#Override
public void run()
{
TimerTask increaseTemperature = new TimerTask(){
public void run() {
try {
//do the processing
} catch (InterruptedException ex) {}
}
};
Timer increaserTimer = new Timer("MyTimer");
//start a 3 seconds timer 10ms later
increaserTimer.scheduleAtFixedRate(increaseTemperature, 3000, 10);
while(true) {
//give it some time to see timer triggering
doSomethingMeaningful();
}
}
I think the method you've used has the signature schedule(TimerTask task, long delay) . So in effect you're just delaying the start time of the ONLY execution.
To schedule it to run every 3 seconds you need to go with this method schedule(TimerTask task, long delay, long period) where the third param is used to give the period interval.
You can refer the Timer class definition here to be of further help
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Timer.html
Timer & TimerTask are legacy
The Timer & TimerTask classes are now legacy. To run code at a certain time, or to run code repeatedly, use a scheduled executor service.
To quote the Timer class Javadoc:
Java 5.0 introduced the java.util.concurrent package and one of the concurrency utilities therein is the ScheduledThreadPoolExecutor which is a thread pool for repeatedly executing tasks at a given rate or delay. It is effectively a more versatile replacement for the Timer/TimerTask combination, as it allows multiple service threads, accepts various time units, and doesn't require subclassing TimerTask (just implement Runnable). Configuring ScheduledThreadPoolExecutor with one thread makes it equivalent to Timer.
Executor framework
In modern Java, we use the Executors framework rather than directly addressing the Thread class.
Define your task as a Runnable or Callable. You can use compact lambda syntax seen below. Or you can use conventional syntax to define a class implementing the Runnable (or Callable) interface.
Ask a ScheduledExecutorService object to execute your Runnable object’s code every so often.
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor() ;
Runnable task = () -> {
System.out.println( "Doing my thing at: " + Instant.now() );
};
long initialDelay = 0L ;
long period = 3L ;
TimeUnit timeUnit = TimeUnit.SECONDS ;
scheduledExecutorService.submit( task , initialDelay, period , timeUnit ) ;
…
scheduledExecutorService.shutdown() ; // Stops any more tasks from being scheduled.
scheduledExecutorService.awaitTermination() ; // Waits until all currently running tasks are done/failed/canceled.
Notice that we are not directly managing any Thread objects in the code above. Managing threads is the job of the executor service.
Tips:
Always shutdown your executor service gracefully when no longer needed, or when your app exits. Otherwise the backing thread pool may continue indefinitely like a zombie 🧟♂️.
Consider wrapping your task's working code in a try-catch. Any uncaught exception or error reaching the scheduled executor service results in silently halting the further scheduling of any more runs.
I'm making a cookie clicker sort of game and I want a thing where every second a certain number let's say 5 is added to another number. So every second the integer variable is going up by 5. How would I create a sort of time measuring method where it measures time so I can add a number to another number.
public class timeTesting {
// I've put this method here for someone to create
// a timer thing
void timer()
{
}
public static void main(String[] args) {
// Original number
int number = 1;
// Number I want added on to the original number every 5 seconds
int addedNumber = 5;
}
}
You can use Timer to schedule a TimerTask who has the desired code inside the run() method. Check the code below (run() will be called once after 5000 milliseconds) :
Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
number += addedNumber;
}
}, 5000);
Also you can use scheduleAtFixedRate(TimerTask task, long delay, long period) for repetitive tasks (here run will be called immediately, and every 5000 milliseconds):
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
number += addedNumber;
}
}, 0, 5000);
If you're targeting the android platform you could use CountDownTimer, which allows you to execute some code every certain amount of time for a certain duration. But be aware that android doesn't work with the main method like J2SE does.
Anyway, if you're looking foward to program an android game, i'd highly recommend you to start here: Android Development
I'd like to suggest start studying RxJava. Reactive programming is very powerful for games development: https://www.youtube.com/watch?v=WKore-AkisY
With RxJava, your problem can be solved with Observable interval() method:
https://github.com/Netflix/RxJava/wiki/Creating-Observables#interval
Ivan
You should consider using a Timer which will fire an event when a certain time interval has passed. It can repeat the event every so often, too.
Not very elegant, but working code:
public class MyTimer {
private volatile int number; //must be volatile as we're working on multiple threads.
private final int numberToAdd;
private final long timerTimeInMillis;
public MyTimer() {
number = 1;
numberToAdd = 5;
timerTimeInMillis = 5000;
}
public void runTimer() {
new Thread() { //declaring a new anonymous Thread class
public void run() { //that has to override run method.
while (true) //run the program in an infinite loop
{
number += numberToAdd; //add a number
System.out.println("Added number. Now the number is: " + number);
try {
Thread.sleep(timerTimeInMillis); //and then sleep for a given time.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start(); //and here we're starting this declared thread
}
public static void main(String[] args)
{
new MyTimer().runTimer();
try {
Thread.sleep(100000); //this application will work for 100sec.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Using java.util.Timer would be more elegant, but in here you may get aquainted with anonymous classes.
I'm a Java beginner and have been futzing around with various solutions to this problem and have gotten myself kind of knotted up. I've tried with Threads and then discovered this Timer class and have messed around with it without success so far. If you could post executable code with a main method so I could see it working and start playing around from there, that would be great.
Launch program
call doSomething()
Generate random number and set Timer for that long.
When Timer goes off, call doSomething() again.
Probably using this: http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html
If you want to simply use Timer, I would do something like this:
public class TestClass {
public long myLong = 1234;
public static void main(String[] args) {
final TestClass test = new TestClass();
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
test.doStuff();
}
}, 0, test.myLong);
}
public void doStuff(){
//do stuff here
}
}
Sorry for the lousy identation.
Also, if you need to schedule execution of code, take a look at Guava Services since it can really make your code much clearer and abstract quite a bit of the boilerplate of creating threads, scheduling, etc.
By the way, I didn't take the trouble of generating random number, etc, but I think you can figure out how to include that part. I hope this is enough to get you on the right track.
For the record, if you were to use Guava, it would look something like this:
class CrawlingService extends AbstractScheduledService {
#Override
protected void runOneIteration() throws Exception {
//run this alot
}
#Override
protected void startUp() throws Exception {
//anything you need to step up
}
#Override
protected void shutDown() throws Exception {
//anything you need to tear down
}
#Override
protected Scheduler scheduler() {
return new CustomScheduler() {
#Override
protected Schedule getNextSchedule() throws Exception {
long a = 1000; //number you can randomize to your heart's content
return new Schedule(a, TimeUnit.MILLISECONDS);
}
};
}
}
And you would simply create a main that called new CrawlingService.start(); that's it.
Do you specifically want a Timer? If not you're probably better off with a ScheduledExecutorService and calling scheduleAtFixedRate or scheduleWithFixedDelay; quoting the Javadocs:
Java 5.0 introduced the java.util.concurrent package and one of the
concurrency utilities therein is the ScheduledThreadPoolExecutor which
is a thread pool for repeatedly executing tasks at a given rate or
delay. It is effectively a more versatile replacement for the
Timer/TimerTask combination, as it allows multiple service threads,
accepts various time units, and doesn't require subclassing TimerTask
(just implement Runnable). Configuring ScheduledThreadPoolExecutor
with one thread makes it equivalent to Timer.
UPDATE
Here's some working code using a ScheduledExecutorService:
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String[] args) {
final ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
System.out.println(new Date());
}
}, 0, 1, TimeUnit.SECONDS);
}
}
The output looks like:
Thu Feb 23 21:20:02 HKT 2012
Thu Feb 23 21:20:03 HKT 2012
Thu Feb 23 21:20:04 HKT 2012
Thu Feb 23 21:20:05 HKT 2012
Thu Feb 23 21:20:06 HKT 2012
Thu Feb 23 21:20:07 HKT 2012
Think of a scenario where I want my code to execute at a particular time in my application or at sometime later from the current time. In other words, I want to schedule my task at the definite time.
Java Timer class (java.util.Timer) allows an application to schedule the task on a separate background thread.
Here is the simplest example of Java Timer:
import java.util.Timer;
import java.util.TimerTask;
public class JavaTimer {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
System.out.println("Inside Timer Task" + System.currentTimeMillis());
}
};
System.out.println("Current time" + System.currentTimeMillis());
timer.schedule(task, 10000,1000);
System.out.println("Current time" + System.currentTimeMillis());
}
}
Output:
Current time1455469505220
Current time1455469505221
Inside Timer Task1455469515222
Inside Timer Task1455469516222
Inside Timer Task1455469517222
Inside Timer Task1455469518222
Inside Timer Task1455469519222
Inside Timer Task1455469520222
Inside Timer Task1455469521222
Inside Timer Task1455469522222
Inside Timer Task1455469523222
Inside Timer Task1455469524222
Inside Timer Task1455469525222
Inside Timer Task1455469526222
Inside Timer Task1455469527222
Inside Timer Task1455469528223
Inside Timer Task1455469529223 and it goes on
ANALYSIS :
The call to timer.schedule(task, 10000,1000) is going to schedule the task which is going to execute for first time (on another thread) after 10 second from this call. After that it will call again after delay of 10 seconds. It is important to mention here that if the task cannot be started after 10 seconds, next task call will not get pre-pond. So here the delay time between two consecutive task is fixed.
Source: Java Timer Example
If you don't want to use timer class and can use Quartz then perform it like. My main class would be
import com.google.common.util.concurrent.AbstractScheduledService;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import static org.quartz.TriggerBuilder.newTrigger;
import java.util.concurrent.CountDownLatch;
public class Test {
public static void main(String[] args) throws Exception{
CountDownLatch latch = new CountDownLatch(1);
//do schdeuling thing
JobDetail job = JobBuilder.newJob(SimpleJob.class).withIdentity(
"CronQuartzJob", "Group").build();
// Create a Trigger that fires every 5 minutes.
Trigger trigger = newTrigger()
.withIdentity("TriggerName", "Group")
.withSchedule(CronScheduleBuilder.cronSchedule("0/1 * * * * ?"))
.build();
// Setup the Job and Trigger with Scheduler & schedule jobs
final Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
//
latch.await();
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
try {
scheduler.shutdown();
latch.countDown();
}catch (Exception e){
e.printStackTrace();
}
}
}));
}
}
and job class would be
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class SimpleJob implements Job {
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("executing task!");
}
}
I would create a executable jar for this and start this using java -jar .. & and Ctrl+C can stop that process , If you want it in background disownit
The below code will run at 18:20 and it will repeat itself in interval of 5 sec.
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask tt = new TimerTask() {
public void run() {
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR_OF_DAY);
int min = cal.get(Calendar.MINUTE);
if (hour == 18 && min == 20) {
doSomething();
}
}
};
timer.schedule(tt, 1000, 5000);
}
I'm trying to use a timer to schedule a recurring event in an application. However, I want to be able to adjust the period at which the event fires in real time (according to the users input).
For example:
public class HelperTimer extends TimerTask
{
private Timer timer;
//Default of 15 second between updates
private int secondsToDelay = 15;
public void setPeriod(int seconds)
{
this.secondsToDelay = seconds;
long delay = 1000; // 1 second
long period = 1000*secondsToDelay; // seconds
if (timer != null)
{
timer.cancel();
}
System.out.println(timer);
timer = new Timer();
System.out.println(timer);
timer.schedule(this, delay, period);
}
public int getPeriod()
{
return this.secondsToDelay;
}
}
I then start a new instance of this class and call its set period function. However, when I do that, I get an Illegal state exception. You can see the System.out.println(timer); in there because I'm checking, and yep sure enough, they are two different timers... so why am I getting an IllegalStateException when I try to run a schedule call on a brand new Timer instance!?!?!?!
java.util.Timer#c55e36
java.util.Timer#9664a1
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Task already scheduled or cancelled
at java.util.Timer.sched(Unknown Source)
at java.util.Timer.schedule(Unknown Source)
at HelperTimer.setPeriod(HelperTimer.java:38)
You can't reuse a TimerTask as you're doing here.
Relevant porition of Timer:
private void sched(TimerTask task, long time, long period) {
if (time < 0)
throw new IllegalArgumentException("Illegal execution time.");
synchronized(queue) {
if (!thread.newTasksMayBeScheduled)
throw new IllegalStateException("Timer already cancelled.");
synchronized(task.lock) {
//Right here's your problem.
// state is package-private, declared in TimerTask
if (task.state != TimerTask.VIRGIN)
throw new IllegalStateException(
"Task already scheduled or cancelled");
task.nextExecutionTime = time;
task.period = period;
task.state = TimerTask.SCHEDULED;
}
queue.add(task);
if (queue.getMin() == task)
queue.notify();
}
}
You'll need to refactor your code so that you create a new TimerTask, rather than re-using one.
It seems odd to me to have a TimerTask with its own Timer inside it. Bad design. I'd totally separate the two and have the TimerTask implementation be handed off to a Timer, and put all that logic about fiddling with the period inside another class that provides an interface for doing so. Let that class instantiate the Timer and TimerTask and send them off to do their work.
You can use ScheduledExecutorService, which allows you to schedule the same task multiple times without using scheduleAtFixedRate. Here's a quick example:
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
Runnable timerTask = new Runnable() {
#Override
public void run() {
// Do something
System.out.println("Task run!");
// Schedule again
executorService.schedule(this, 15, TimeUnit.SECONDS);
}
};
// Schedule
executorService.schedule(timerTask, 15, TimeUnit.SECONDS);
In this exmaple, "Executed...." will be printed after 4 seconds of delay. After that, it will be printed continuously every 3 seconds:
import java.util.*;
class TimeSetting {
public static void main(String[] args) {
Timer t = new Timer();
TimerTask time = new TimerTask() {
public void run() {
System.out.println("Executed......");
}
};
t.scheduleAtFixedRate(time, 4000, 3000);
/*
* The task will be started after 4 secs and
* for every 3 seconds the task will be continuously
* executed.....
*/
}
}
I'd like to have a java.utils.Timer with a resettable time in java.I need to set a once off event to occur in X seconds. If nothing happens in between the time the timer was created and X seconds, then the event occurs as normal.
If, however, before X seconds has elapsed, I decide that the event should occur after Y seconds instead, then I want to be able to tell the timer to reset its time so that the event occurs in Y seconds.
E.g. the timer should be able to do something like:
Timer timer = new Timer();
timer.schedule(timerTask, 5000); //Timer starts in 5000 ms (X)
//At some point between 0 and 5000 ms...
setNewTime(timer, 8000); //timerTask will fire in 8000ms from NOW (Y).
I don't see a way to do this using the utils timer, as if you call cancel() you cannot schedule it again.
The only way I've come close to replicating this behavior is by using javax.swing.Timer and involves stopping the origional timer, and creating a new one. i.e.:
timer.stop();
timer = new Timer(8000, ActionListener);
timer.start();
Is there an easier way??
According to the Timer documentation, in Java 1.5 onwards, you should prefer the ScheduledThreadPoolExecutor instead. (You may like to create this executor using Executors.newSingleThreadScheduledExecutor() for ease of use; it creates something much like a Timer.)
The cool thing is, when you schedule a task (by calling schedule()), it returns a ScheduledFuture object. You can use this to cancel the scheduled task. You're then free to submit a new task with a different triggering time.
ETA: The Timer documentation linked to doesn't say anything about ScheduledThreadPoolExecutor, however the OpenJDK version had this to say:
Java 5.0 introduced the java.util.concurrent package and
one of the concurrency utilities therein is the
ScheduledThreadPoolExecutor which is a thread pool for repeatedly
executing tasks at a given rate or delay. It is effectively a more
versatile replacement for the Timer/TimerTask
combination, as it allows multiple service threads, accepts various
time units, and doesn't require subclassing TimerTask (just
implement Runnable). Configuring
ScheduledThreadPoolExecutor with one thread makes it equivalent to
Timer.
If your Timer is only ever going to have one task to execute then I would suggest subclassing it:
import java.util.Timer;
import java.util.TimerTask;
public class ReschedulableTimer extends Timer
{
private Runnable task;
private TimerTask timerTask;
public void schedule(Runnable runnable, long delay)
{
task = runnable;
timerTask = new TimerTask()
{
#Override
public void run()
{
task.run();
}
};
this.schedule(timerTask, delay);
}
public void reschedule(long delay)
{
timerTask.cancel();
timerTask = new TimerTask()
{
#Override
public void run()
{
task.run();
}
};
this.schedule(timerTask, delay);
}
}
You will need to work on the code to add checks for mis-use, but it should achieve what you want. The ScheduledThreadPoolExecutor does not seem to have built in support for rescheduling existing tasks either, but a similar approach should work there as well.
The whole Code snippet goes like this .... I hope it will be help full
{
Runnable r = new ScheduleTask();
ReschedulableTimer rescheduleTimer = new ReschedulableTimer();
rescheduleTimer.schedule(r, 10*1000);
public class ScheduleTask implements Runnable {
public void run() {
//Do schecule task
}
}
class ReschedulableTimer extends Timer {
private Runnable task;
private TimerTask timerTask;
public void schedule(Runnable runnable, long delay) {
task = runnable;
timerTask = new TimerTask() {
public void run() {
task.run();
}
};
timer.schedule(timerTask, delay);
}
public void reschedule(long delay) {
System.out.println("rescheduling after seconds "+delay);
timerTask.cancel();
timerTask = new TimerTask() {
public void run() {
task.run();
}
};
timer.schedule(timerTask, delay);
}
}
}
Do you need to schedule a recurring task? In that case I recommend you consider using Quartz.
I don't think it's possible to do it with Timer/TimerTask, but depending on what exactly you want to achieve you might be happy with using java.util.concurrent.ScheduledThreadPoolExecutor.
this is what I'm trying out. I have a class that polls a database every 60 seconds using a TimerTask.
in my main class, I keep the instance of the Timer, and an instance of my local subclass of TimerTask. the main class has a method to set the polling interval (say going from 60 to 30). in it, i cancel my TimerTask (which is my subclass, where I overwrote the cancel() method to do some cleanup, but that shouldn't matter) and then make it null. i recreate a new instance of it, and schedule the new instance at the new interval in the existing Timer.
since the Timer itself isn't canceled, the thread it was using stays active (and so would any other TimerTasks inside it), and the old TimerTask is replaced with a new one, which happens to be the same, but VIRGIN (since the old one would have been executed or scheduled, it is no longer VIRGIN, as required for scheduling).
when i want to shutdown the entire timer, i cancel and null the TimerTask (same as i did when changing the timing, again, for cleaning up resources in my subclass of TimerTask), and then i cancel and null the Timer itself.
Here is the example for Resetable Timer . Try to change it for your convinence...
package com.tps.ProjectTasks.TimeThread;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* Simple demo that uses java.util.Timer to schedule a task to execute
* every 5 seconds and have a delay if you give any input in console.
*/
public class DateThreadSheduler extends Thread {
Timer timer;
BufferedReader br ;
String data = null;
Date dNow ;
SimpleDateFormat ft;
public DateThreadSheduler() {
timer = new Timer();
timer.schedule(new RemindTask(), 0, 5*1000);
br = new BufferedReader(new InputStreamReader(System.in));
start();
}
public void run(){
while(true){
try {
data =br.readLine();
if(data != null && !data.trim().equals("") ){
timer.cancel();
timer = new Timer();
dNow = new Date( );
ft = new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
System.out.println("Modified Current Date ------> " + ft.format(dNow));
timer.schedule(new RemindTask(), 5*1000 , 5*1000);
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) {
System.out.format("Printint the time and date was started...\n");
new DateThreadSheduler();
}
}
class RemindTask extends TimerTask {
Date dNow ;
SimpleDateFormat ft;
public void run() {
dNow = new Date();
ft = new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
System.out.println("Current Date: " + ft.format(dNow));
}
}
This example prints the current date and time for every 5 seconds...But if you give any input in console the timer will be delayed to perform the given input task...
I made an own timer class for a similar purpose; feel free to use it:
public class ReschedulableTimer extends Timer {
private Runnable mTask;
private TimerTask mTimerTask;
public ReschedulableTimer(Runnable runnable) {
this.mTask = runnable;
}
public void schedule(long delay) {
if (mTimerTask != null)
mTimerTask.cancel();
mTimerTask = new TimerTask() {
#Override
public void run() {
mTask.run();
}
};
this.schedule(mTimerTask, delay);
}
}