My requirement is I want to schedule a task that should run once a day.For that I am using following code:
public class setAutoReminder {
EscalationDAO escalationDAO=new EscalationDAO();
final SendMail sendMail=new SendMail();
public void fetch(){
Date date=new Date();
Timer timer = new Timer();
timer.schedule(new TimerTask(){
public void run(){
int number=escalationDAO.getAutoReminder();
System.out.println(number);
if(number>0) {
sendMail.sendMail();
}
}
},date, 1000000000);
}
}
but this code runs multiple times.I want it to runs once a day.What should I do?
If you don't have many scheduled jobs then don't add all the Spring baggage.
Keep it simple.
Date date=new Date();
Timer timer = new Timer();
timer.schedule(new TimerTask(){
public void run(){
System.out.println("Im Running..."+new Date());
}
},date, 24*60*60*1000);//24*60*60*1000 add 24 hours delay between job executions.
This will do the stuff.
-Siva
With Spring (using lombok #Slf4j):
#Slf4j
#Component
public class SetAutoReminder
{
#Autowired
private EscalationDAO escalationDAO;
#Autowired
private SendMail sendMail;
#Scheduled(cron = "0 0 0 * * *") // everyday at midnight
public void fetch(){
final int number = escalationDAO.getAutoReminder();
log.debug("Today number: {}", number);
if (number>0) {
sendMail.sendMail();
}
}
}
Tutorial on spring scheduling: springsource blog
You need a scheduler, like Quartz Scheduler
Related
I want to push a notification every 12 hours at fixed times (lets say for an example, 9am and 9pm, every day). This is my current doWork() code:
#NonNull
#Override
public Result doWork() {
database.child("business_users").child(currentUserID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
user = snapshot.getValue(BusinessUser.class);
if(user.isNotifications()==true)
{
if(user.getRatingsCount() > user.getLastKnownRC())
{
theDifference = user.getRatingsCount() - user.getLastKnownRC();
notification();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Log.i("BackgroundWork" , "notif sent");
return Result.success();
}
`
and this is the work creation code:
public void FirstTimeWork ()
{
PeriodicWorkRequest myWorkRequest =
new PeriodicWorkRequest.Builder(BackgroundWork.class, 12, TimeUnit.HOURS)
.setInitialDelay(1, TimeUnit.DAYS)
.addTag("notif")
.build();
}
I saw some people doing it with calendar but I don't understand how it works.
The #EnableScheduling annotation is used to enable the scheduler for your application. This annotation should be added into the main Spring Boot application class file.
#SpringBootApplication
#EnableScheduling
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
The #Scheduled annotation is used to trigger the scheduler for a specific time period.
#Scheduled(cron = "0 * 9 * * ?")
public void cronJobSch() throws Exception {
}
The following is a sample code that shows how to execute the task every minute starting at 9:00 AM and ending at 9:59 AM, every day
package com.tutorialspoint.demo.scheduler;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
#Component
public class Scheduler {
#Scheduled(cron = "0 * 9 * * ?")
public void cronJobSch() {
System.out.println(LocalDateTime.now());
}
}
You can use class Timer. Then, your background job must be implemented in a subclass to TimerTask in the overridden method public void run(), e.g.:
public class BackgroundWork extends TimerTask {
#Override
public void run() {
// Do your background work here
Log.i("BackgroundWork" , "notif sent");
}
}
You can schedule this job as follows:
// void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
Date date = new Date( 122, 04, 02, 9, 00 );
(new Timer()).scheduleAtFixedRate(new BackgroundWork(), date, 43200000L);
Timer starts a new thread to execute this job. You can cancel it, if necessary.
I have found a simple solution, using calendar:
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 22);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
if (calendar.getTimeInMillis() <= System.currentTimeMillis()) {
calendar.set(Calendar.DAY_OF_MONTH, Calendar.DAY_OF_MONTH + 1);
}
and the initial delay is set like so:
.setInitialDelay(calendar.getTimeInMillis() - System.currentTimeMillis(), TimeUnit.MILLISECONDS)
and this seems to work well.
Use ScheduledExecutorService
ScheduledExecutorService scheduledExecutorService
= Executors.newScheduledThreadPool(CORE_POOL_SIZE);
// Calculate initial day based on the current time
Long initalDelay = 0l;
ScheduledFuture<?> scheduledFuture =
scheduledExecutorService.scheduleAtFixedRate(doWork(), initalDelay, 12l, TimeUnit.HOURS);
I am writing a web crawler and part of the specifications is that it will crawl the web for a user-specified amount of time. In order to do that I am trying to use the Timer and TimerTask methods. The code I have now is attempt number two. I have watched a few tutorials though none of them are quite what I need. I have also read through the documentation. I have been working on this project for a few weeks now and it is due tonight. I am not sure where to turn to next.
public void myTimer (String url, long time)
{
Timer webTimer = new Timer();
TimerTask timer;
timer = new TimerTask()
{
public void run()
{
long limit = calculateTimer(time);
while(System.currentTimeMillis() < limit)
{
webcrawler crawler1 = new webcrawler();
crawler1.Crawl(url);
}
System.out.println("times Up");
}
};
webTimer.schedule(timer, 1000);
}
I am guessing the .Crawl() is starting a loop and keeping that thread busy, which means it cannot check the while condition. I do not know your implementation of the crawler but i would recommend a function stopCrawling which would set a boolean to true to break the loop inside that class. Than I would do something like this:
public void startCrawler (String url, long time){
webcrawler crawler1 = new webcrawler();
crawler1.Crawl(url);
TimerTask task = new TimerTask() {
public void run() {
crawler1.stopCrawling()
}
};
Timer timer = new Timer("Timer");
timer.schedule(task, time);
}
I want schedule one java program to run at 15th,25th and 45th min of time every hour. For example:
17:15 , 17:25 , 17:45 , 18:15 and so on...
How can I acheive this using ScheduledExecutorService. I can see several examples which can trigger scripts after certain time intervals with respect to the time they are triggered using ScheduledExecutorService.
Can anyone suggest me relevent links and examples to get some idea
I could not find a way to schedule a Timer with uneven intervals. However, it is relatively straightforward to schedule a Timer to execute at fixed intervals.
For your case, you could schedule three timers, one for :15, one for :25, and one for :45 past the hour:
public class TaskTest {
public static scheduleTask(int interval) {
GregorianCalendar cal = new GregorianCalendar();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int date = cal.get(Calendar.DATE);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int hourScheduled = hour;
// if we are past the scheduled time then schedule for the next hour
if (minute > interval) {
++hourScheduled;
}
cal.set(year, month, date, hourScheduled, interval);
long initialDelay = cal.getTimeInMillis() - System.currentTimeMillis();
if (initialDelay < 0) {
initialDelay = 0L;
}
// schedule each job for once per hour
int period = 60*60*1000;
Timer timer = new Timer();
SomeTask someTask = new SomeTask();
timer.scheduleAtFixedRate(someTask, initialDelay, period);
}
public static void main(String[] args) {
// schedule for the 15th, 25th and 45th min of time every hour
scheduleTask(15);
scheduleTask(25);
scheduleTask(45);
}
}
public class SomeTask extends TimerTask {
#Override
public void run() {
// do something
}
}
You want to trigger your code at some time point, not periodically, I think there are several choices:
if your program run under Linux or other systems which support crontab, then crontab is a good choice.
We could create multi cron job to achieve your target:
use command "crontab -e" to edit cron jobs:
15 * * * * /java_path/java your_program parameters
25 * * * * /java_path/java your_program parameters
35 * * * * /java_path/java your_program parameters
45 * * * * /java_path/java your_program parameters
if you don't want to use crontab, and you just want a pure java solution, quartz will help you.
quartz could let you configure cron triggers which are little like crontab under Linux.
please refer to http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-06.html to get more information.
At last, you want a pure java, and lightweight solution, you could simply use Java Timer and TimerTask, such as:
public class App {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask tt = new SchedulerTask();
DateFormat df = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
Date triggerTime = null;
try {
triggerTime = df.parse("2016-04-12 13:15:00");
} catch (ParseException e) {
e.printStackTrace();
}
timer.schedule(tt, triggerTime, 3600*1000);
}
static class SchedulerTask extends TimerTask {
#Override
public void run() {
System.out.println("I am running at " + Calendar.getInstance().getTime());
}
}
}
you could create 4 tasks like the task above, trigger at 13:15, 13:25, 13:35, 13:45 and each task runs once for every hour.
You can schedule same runnable with fixed 1hour interval & delay should be variable based on current time.
Example current time 6:10 than delay for your first schedule will be 5min(6:15), for second schedule 5+10=15 min(6:25).
like that you can create multiple schedule each with one hour delays.
import java.util.GregorianCalendar;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class MultipleScheduler {
public static void main(String[] args) {
Runnable task = new Runnable() {
#Override
public void run() {
System.out.println(System.currentTimeMillis() + " Task executed");
}
};
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
int BaseDelay = getInitialDelay();
service.scheduleAtFixedRate(task, BaseDelay, 60, TimeUnit.MINUTES);
service.scheduleAtFixedRate(task, BaseDelay + 10, 60, TimeUnit.MINUTES);
service.scheduleAtFixedRate(task, BaseDelay + 30, 60, TimeUnit.MINUTES);
}
static int getInitialDelay() {
GregorianCalendar cal = new GregorianCalendar();
int minute=cal.get(cal.MINUTE);
int delay=0;
//some logic to calculate delay updated delay should be returned
return delay;
}
}
I need to do a periodic operation (call a java method) in my web app (jsp on tomcat).
How can i do this ? Java daemon or others solutions ?
You could use a ScheduledExecutorService for periodic execution of a task. However, if you require more complex cron-like scheduling then take a look at Quartz. In particular I'd recommend using Quartz in conjunction with Spring if you go down this route, as it provides a nicer API and allows you to control your job firing in configuration.
ScheduledExecutorService Example (taken from Javadoc)
import static java.util.concurrent.TimeUnit.*;
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);
}
}
Adams answer is right on the money. If you do end up rolling your own (rather than going the quartz route), you'll want to kick things off in a ServletContextListener. Here's an example, using java.util.Timer, which is more or less a dumb version of the ScheduledExexutorPool.
public class TimerTaskServletContextListener implements ServletContextListener
{
private Timer timer;
public void contextDestroyed( ServletContextEvent sce )
{
if (timer != null) {
timer.cancel();
}
}
public void contextInitialized( ServletContextEvent sce )
{
Timer timer = new Timer();
TimerTask myTask = new TimerTask() {
#Override
public void run()
{
System.out.println("I'm doing awesome stuff right now.");
}
};
long delay = 0;
long period = 10 * 1000; // 10 seconds;
timer.schedule( myTask, delay, period );
}
}
And then this goes in your web.xml
<listener>
<listener-class>com.TimerTaskServletContextListener</listener-class>
</listener>
Just more food for thought!
HI
I want to run a method in my program evry X hours, how to do that ?
Im googling and there is nothing :/
You could consider Quartz.
It is some sort of cron that runs inside java. I admit though that it is probably an overkill if you want to schedule only one job.
You could take a look at the Timer class, but the best option is to use a ScheduledExecutorService:
e.g. This will beep at a scheduled rate:
import static java.util.concurrent.TimeUnit.*;
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);
}
}
I use the Quartz framework for most of my scheduling ( http://www.quartz-scheduler.org/ ) but if you're doing something simple, java.util.Timer is fine.
// in a class body...
public static void main( String[] argv ) {
Timer timer = new Timer();
int secondsBetweenRuns = 3600;
timer.schedule( new MyOwnTask(), 0, secondsBetweenRuns * 1000 );
}
static class MyOwnTask extends TimerTask {
public void run() {
doWhateverYouNeedToDoEveryHour();
}
}
Scheduled Task (in Windows) or Cron (in Unix)
You could save the time at a certain point, than start a timer. When the time is up, you run the method and restart the timer.