How to read Spring Boot api every minute [duplicate] - java

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.

Related

How to check if Thread is running inside a servlet [duplicate]

I'm using Java and I want to keep a servlet continuously running in my application, but I'm not getting how to do it. My servlet has a method which gives counts of the user from a database on a daily basis as well as the total count of the users from the whole database. So I want to keep the servlet continuously running for that.
Your problem is that you misunderstand the purpose of the servlet. It's intented to act on HTTP requests, nothing more. You want just a background task which runs once on daily basis.
EJB available? Use #Schedule
If your environment happen to support EJB (i.e. a real Java EE server such as WildFly, JBoss, TomEE, Payara, GlassFish, etc), then use #Schedule instead. Here are some examples:
#Singleton
public class BackgroundJobManager {
#Schedule(hour="0", minute="0", second="0", persistent=false)
public void someDailyJob() {
// Do your job here which should run every start of day.
}
#Schedule(hour="*/1", minute="0", second="0", persistent=false)
public void someHourlyJob() {
// Do your job here which should run every hour of day.
}
#Schedule(hour="*", minute="*/15", second="0", persistent=false)
public void someQuarterlyJob() {
// Do your job here which should run every 15 minute of hour.
}
#Schedule(hour="*", minute="*", second="*/5", persistent=false)
public void someFiveSecondelyJob() {
// Do your job here which should run every 5 seconds.
}
}
Yes, that's really all. The container will automatically pickup and manage it.
EJB unavailable? Use ScheduledExecutorService
If your environment doesn't support EJB (i.e. you're not using not a real Java EE server, but a barebones servletcontainer such as Tomcat, Jetty, etc), then use ScheduledExecutorService. This can be initiated by a ServletContextListener. Here's a kickoff example:
#WebListener
public class BackgroundJobManager implements ServletContextListener {
private ScheduledExecutorService scheduler;
#Override
public void contextInitialized(ServletContextEvent event) {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 1, TimeUnit.DAYS);
scheduler.scheduleAtFixedRate(new SomeHourlyJob(), 0, 1, TimeUnit.HOURS);
scheduler.scheduleAtFixedRate(new SomeQuarterlyJob(), 0, 15, TimeUnit.MINUTES);
scheduler.scheduleAtFixedRate(new SomeFiveSecondelyJob(), 0, 5, TimeUnit.SECONDS);
}
#Override
public void contextDestroyed(ServletContextEvent event) {
scheduler.shutdownNow();
}
}
Where the job classes look like this:
public class SomeDailyJob implements Runnable {
#Override
public void run() {
// Do your daily job here.
}
}
public class SomeHourlyJob implements Runnable {
#Override
public void run() {
// Do your hourly job here.
}
}
public class SomeQuarterlyJob implements Runnable {
#Override
public void run() {
// Do your quarterly job here.
}
}
public class SomeFiveSecondelyJob implements Runnable {
#Override
public void run() {
// Do your quarterly job here.
}
}
Do not ever think about using java.util.Timer/java.lang.Thread in a Java EE / Servlet based environment
Last but not least, never directly use java.util.Timer and/or java.lang.Thread in Java EE. This is recipe for trouble. An elaborate explanation can be found in this JSF-related answer on the same question: Spawning threads in a JSF managed bean for scheduled tasks using a timer.
I would suggest using a library like quartz in order to run the task at regular intervals. What does the servlet really do ? It sends you a report ?
You can use cron4j. http://www.sauronsoftware.it/projects/cron4j/manual.php
Implement two classes and call startTask() in main.
public void startTask()
{
// Create a Runnable
Runnable task = new Runnable() {
public void run() {
while (true) {
runTask();
}
}
};
// Run the task in a background thread
Thread backgroundThread = new Thread(task);
// Terminate the running thread if the application exits
backgroundThread.setDaemon(true);
// Start the thread
backgroundThread.start();
}
public void runTask()
{
try {
// do something...
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
In a production system that may have multiple non-jee containers running. Use anot enterprise scheduler like Quartz scheduler which can be configured to use a database for task maamgememt.

Run Java code once every hour

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());
}
}

How to use Timer class to call a method, do something, reset timer, repeat?

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);
}

Java Timer

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.....
*/
}
}

Resettable Java 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);
}
}

Categories

Resources