I'm tryng to write a simple Java program that runs some code every hour when the minute hand is at 20. The issue is that that the way I'm doing it is incredibly CPU intensive. I'm familiar with Quartz but I'm looking for a much simpler solution, any ideas?
boolean run = true;
while(run){
Calendar calendar = new GregorianCalendar();
int minute = calendar.get(Calendar.MINUTE);
if(minute == 20){
//Do some Stuff
}
}
A simple solution is to use the Executors framework:
final ScheduledExecutorService s = Executors.newSingleThreadScheduledExecutor();
s.scheduleAtFixedRate(task, secondsToFirstOccurence, 60*60, TimeUnit.SECONDS);
And use some logic to find out secondsToFirstOccurence. This will probably involve a Calendar instance, but would be much more convenient with JodaTime.
Be aware that if your application is running inside a managed environment (a web or ejb container) you're not allowed to use Thread.sleep() or any other thread-related operations, for that matter, take a look at the EJB restrictions page. I warn about this because the question is tagged java-ee, so the "simple application" might not be so simple after all - if it's running inside a Java EE container there are additional considerations to take care of.
If you're building an enterprise-grade application, forget about Thread.sleep(). Go for a full-fledged job scheduler, Use Quartz, it's an open source and extremely mature and reliable product. Or use Obsidian Scheduler, a feature-rich commercial scheduler with more out-of-the-box features than Quartz.
A lightweight alternative to a full-fledged scheduler (but suitable for running inside a container) would be to use the Timer service.
You might be looking for Thread.sleep() between calls
Look at java.util.Timer method scheduleAtFixedRate().
I would suggest that you remove the scheduling logic from your java program. By doing this you are able to focus only on what you want your program to do and leave the scheduling part to the OS. Also, say for example you decide at some point to write a c++ program that does what your java code does know, you won't have to implement the cron logic in your new programThat being said:
for Linux you have crontab
for Windows you have windows task schedule
for Mac, I am not sure, but given the fact it is UNIX based cron should be present.
Put your code in an infinite while and use
Thread.sleep(3600000);
Start the execution at 20 after
Example
while(1==1) {
//Your code here
try{
Thread.sleep(3600000);
}
catch (Exception e) {}
}
Schedule a cron job for the method that you want to execute hourly rather going for blocking sleep() call, Use some scheduling framework like quartz
You should have a look at ScheduledExecutorService
class BeeperControl {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep"); }
};
final ScheduledFuture<?> beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
scheduler.schedule(new Runnable() {
public void run() { beeperHandle.cancel(true); }
}, 60 * 60, SECONDS);
}
}
Use something like this
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 20);
calendar.set(Calendar.MINUTE, 20);
calendar.set(Calendar.SECOND, 0);
Date time = calendar.getTime();
Timer timer = new Timer();
timer.schedule(new SomeTask(), time);
and then reschedule
So definitely the ScheduledExecutorService is fantastic as many of the other answers state.
In the event you're in a Java EE 6 server, you could have some fun with #Schedule and ScheduleExpression
See Have an EJB schedule tasks with "crontab syntax"
1) On first entry calculate next due time.
2) Use java.util.Timer.schedule()
3) Reschedule each run.
Code
package tests;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class App201210130040 {
private static Timer timer = new Timer(false);
public static void schedule() {
Calendar due = Calendar.getInstance();
due.set(Calendar.MINUTE, 20);
if( due.before(Calendar.getInstance()) ) {
due.add(Calendar.HOUR, 1);
}
System.out.println("Scheduled to " + due.getTime().toString());
timer.schedule(new TimerTask() {
#Override
public void run() {
System.out.println("due");
schedule();
}
}, due.getTime());
}
public static void main(String[] args) {
schedule();
}
}
Another example
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestHour {
private static final int MINUNTE = 20;
public static void main(String args[]) {
while (true) {
SimpleDateFormat bartDateFormat = new SimpleDateFormat("mm");
Date date = new Date();
int currentMin = new Integer(bartDateFormat.format(date))
.intValue();
if (currentMin < MINUNTE) {
sleepMinutes(MINUNTE - currentMin);
} else if (currentMin > MINUNTE) {
sleepMinutes(60 - currentMin + MINUNTE);
} else {
// DO SOMETHING EVERY HOUR
System.out.println("come on do it!!!");
sleepMinutes(60);
}
}
}
private static void sleepMinutes(int minutes) {
try {
System.out.println("Sleeping for " + minutes);
Thread.sleep(minutes * 1000*60);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Yet even another example with the things learned today.
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class SchedulerExample2 implements Runnable{
public static void main(String args[]) {
Calendar due = Calendar.getInstance();
due.set(Calendar.MILLISECOND, 0);
due.set(Calendar.SECOND, 0);
due.set(Calendar.MINUTE, 20);
if (due.before(Calendar.getInstance())) {
due.add(Calendar.HOUR, 1);
}
long milliSecondsToNextOcurrence = due.getTimeInMillis() - new Date().getTime();
final ScheduledExecutorService s = Executors.newSingleThreadScheduledExecutor();
ShedulerExample task = new ShedulerExample();
s.scheduleAtFixedRate(task, milliSecondsToNextOcurrence, 60*60*1000, TimeUnit.MILLISECONDS);
}
#Override
public void run() {
System.out.println("hola->"+new Date());
}
}
Related
I need to schedule a task to run in at fixed interval of time. How can I do this with support of long intervals (for example on each 8 hours)?
I'm currently using java.util.Timer.scheduleAtFixedRate. Does java.util.Timer.scheduleAtFixedRate support long time intervals?
Use a ScheduledExecutorService:
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(yourRunnable, 8, 8, TimeUnit.HOURS);
You should take a look to Quartz it's a java framework wich works with EE and SE editions and allows to define jobs to execute an specific time
Try this way ->
Firstly create a class TimeTask that runs your task, it looks like:
public class CustomTask extends TimerTask {
public CustomTask(){
//Constructor
}
public void run() {
try {
// Your task process
} catch (Exception ex) {
System.out.println("error running thread " + ex.getMessage());
}
}
}
Then in main class you instantiate the task and run it periodically started by a precised date:
public void runTask() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 40);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Timer time = new Timer(); // Instantiate Timer Object
// Start running the task on Monday at 15:40:00, period is set to 8 hours
// if you want to run the task immediately, set the 2nd parameter to 0
time.schedule(new CustomTask(), calendar.getTime(), TimeUnit.HOURS.toMillis(8));
}
Use Google Guava AbstractScheduledService as given below:
public class ScheduledExecutor extends AbstractScheduledService {
#Override
protected void runOneIteration() throws Exception {
System.out.println("Executing....");
}
#Override
protected Scheduler scheduler() {
return Scheduler.newFixedRateSchedule(0, 3, TimeUnit.SECONDS);
}
#Override
protected void startUp() {
System.out.println("StartUp Activity....");
}
#Override
protected void shutDown() {
System.out.println("Shutdown Activity...");
}
public static void main(String[] args) throws InterruptedException {
ScheduledExecutor se = new ScheduledExecutor();
se.startAsync();
Thread.sleep(15000);
se.stopAsync();
}
}
If you have more services like this, then registering all services in ServiceManager will be good as all services can be started and stopped together. Read here for more on ServiceManager.
If you want to stick with java.util.Timer, you can use it to schedule at large time intervals. You simply pass in the period you are shooting for. Check the documentation here.
Do something every one second
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
//code
}
}, 0, 1000);
These two classes can work together to schedule a periodic task:
Scheduled Task
import java.util.TimerTask;
import java.util.Date;
// Create a class extending TimerTask
public class ScheduledTask extends TimerTask {
Date now;
public void run() {
// Write code here that you want to execute periodically.
now = new Date(); // initialize date
System.out.println("Time is :" + now); // Display current time
}
}
Run Scheduled Task
import java.util.Timer;
public class SchedulerMain {
public static void main(String args[]) throws InterruptedException {
Timer time = new Timer(); // Instantiate Timer Object
ScheduledTask st = new ScheduledTask(); // Instantiate SheduledTask class
time.schedule(st, 0, 1000); // Create task repeating every 1 sec
//for demo only.
for (int i = 0; i <= 5; i++) {
System.out.println("Execution in Main Thread...." + i);
Thread.sleep(2000);
if (i == 5) {
System.out.println("Application Terminates");
System.exit(0);
}
}
}
}
Reference https://www.mkyong.com/java/how-to-run-a-task-periodically-in-java/
If your application is already using Spring framework, you have Scheduling built in
I use Spring Framework's feature. (spring-context jar or maven dependency).
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
#Component
public class ScheduledTaskRunner {
#Autowired
#Qualifier("TempFilesCleanerExecution")
private ScheduledTask tempDataCleanerExecution;
#Scheduled(fixedDelay = TempFilesCleanerExecution.INTERVAL_TO_RUN_TMP_CLEAN_MS /* 1000 */)
public void performCleanTempData() {
tempDataCleanerExecution.execute();
}
}
ScheduledTask is my own interface with my custom method execute, which I call as my scheduled task.
You can also use JobRunr, an easy to use and open-source Java Scheduler.
To schedule a Job every 8 hours using JobRunr, you would use the following code:
BackgroundJob.scheduleRecurrently(Duration.ofHours(8), () -> yourService.methodToRunEvery8Hours());
If you are using Spring Boot, Micronaut or Quarkus, you can also use the #Recurring annotation:
public class YourService {
#Recurring(interval="PT8H")
public void methodToRunEvery8Hours() {
// your business logic
}
}
JobRunr also comes with an embedded dashboard that allows you to follow-up on how your jobs are doing.
Have you tried Spring Scheduler using annotations ?
#Scheduled(cron = "0 0 0/8 ? * * *")
public void scheduledMethodNoReturnValue(){
//body can be another method call which returns some value.
}
you can do this with xml as well.
<task:scheduled-tasks>
<task:scheduled ref = "reference" method = "methodName" cron = "<cron expression here> -or- ${<cron expression from property files>}"
<task:scheduled-tasks>
my servlet contains this as a code how to keep this in scheduler if a user presses accept
if(bt.equals("accept")) {
ScheduledExecutorService scheduler=Executors.newScheduledThreadPool(1);
String lat=request.getParameter("latlocation");
String lng=request.getParameter("lnglocation");
requestingclass.updatelocation(lat,lng);
}
There is a ScheduledFuture class in java.util.concurrent, it may helps you.
I want to run a task at a specific time say at 7.11pm everyday.
I have tried the following piece of code but it is not working.
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Task3 {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
public void run() {
System.out.println(new Date());
System.out.println("Hello !!");
}
};
Calendar calendar = Calendar.getInstance();
long now = calendar.getTimeInMillis();
calendar.set(Calendar.HOUR, 18);
calendar.set(Calendar.MINUTE, 11);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(runnable, calendar.getTimeInMillis(), 5, TimeUnit.SECONDS);
}
}
In the above code, I have tried to run the schedule task starting from 7:11pm everyday with an interval of 5 seconds. But it is not behaving as I expected to be. And also If I want to do the same with another condition that the task should be executed only on specific days let's say every Tuesday and Wednesday.
Am I making some kind of mistake in calculating the initialDelay parameter of the method or something else?
Side comment: it would probably be simpler to use an ad hoc library (such as quartz).
The initialDelay parameter gives the number of time unit to wait before running the task. In your case, you need to calculate the time left to 7:11.
So it could look like:
long nextRun = calendar.getTimeInMillis();
long initialDelayMillis = nextRun - now;
long oneDayMillis = 1000L * 60 * 60 * 24;
service.scheduleAtFixedRate(runnable, initialDelayMillis, oneDayMillis, TimeUnit.MILLISECONDS);
but this will only handle basic situations. In particular it won't handle clock adjustments or DST at all. And it won't be easy to say "only on Tuesdays and Wendesdays".
An alternative would be to only schedule the next run and reschedule it at the end of the runnable. That way you can have a finer control on the execution. But bottom line is: see my initial comment.
Preferable would be the scheduledExecutorService.
But maybe timer could be used too. For swing the other timer.
Here an example (the timer and timerTask could be stoped with cancel/purge).
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimeScheduleTest {
Timer timer = new Timer();
public static void main(String[] args) {
new TimeScheduleTest().startApp();
}
private void startApp() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK,Calendar.TUESDAY);
calendar.set(Calendar.HOUR_OF_DAY, 7);
calendar.set(Calendar.MINUTE, 11);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
timer.scheduleAtFixedRate(new StartTimer(), calendar.getTime(), 5000);
}
class StartTimer extends TimerTask {
public void run() {
System.out.println(new Date());
System.out.println("Hello !!");
}
}
}
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 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();
}
}
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);
}
}