I am developing Java REST Web Service using Spring and Hibernate. I need to implement a feature to schedule a future task. For example, When User Sign Up in my application I have to credit him 100 virtual credits to his account for first six months. Like this there is some more similar features.
I am thinking like TimerTask can be used for this feature. The problem is If I create Timer for each users who sign up, I can't able to stop Timer of specific user if he goes inactive and it seems like dumping Thread in memory. If 1000 users sign up there will be 1000 TimerTask Threads.
How to implement this kind of feature using Spring or Java? I should have the full control over the Thread, I can able to stop thread If I want.
you can use a Single thread to perform a task with #scheduled annotation and minimal XML configuration, I'll leave the link for your reference.
you're just required to create a method in your service and place #Scheduled annotation like
#Scheduled(cron = "0 15 10 15 * ?")
public void scheduleTaskUsingCronExpression(){
long now = System.currentTimeMillis() / 1000;
System.out.println("schedule tasks using cron jobs - " + now);
}
Related
I have an UI Interface where user can define Job name, interval, active/Inactive etc.
How we can achieve this with Quartz Scheduler or any java/Spring api ?
Ex. Suppose any Quartz job is started and interval is set as 10 min, So in ideal case job will run in next 10 min interval. But every time job runs we want to fetch the latest interval from database and schedule it.
10:00 Job runs and in the database interval is set to 10 min
10:10 Job runs and in the database interval is set to 20 min
So next time job should run at 10:30
If you use Quartz, you can implement a custom Trigger. Your implementation would lookup the value in the database and return when the next time the run should happen in the getFireTimeAfter.
Another option is to use Spring Scheduling APIs and implement the Trigger interface. Same here, the nextExecutionTime method would decide when the next run should happen.
The advantage of using a custom implementation is that you have full control over the triggering logic (like in your case, do a lookup in the database and dynamically set the next run time).
In my Spring program, I have a Scheduled task.
#Scheduled(cron = "0 0 0 2 * *") // hardcoded schedule
public void executeBatchJob() {
batchJob.execute();
}
I have a specification change and now have to let the user freely configure the date and time of execution via an API.
One way I came up was to run a scheduled task every morning at 0:00 and check if the date is indeed the date of execution. If true, check the time of execution and schedule the batch job to run at that time of the day.
Is there a "Spring" way of achieving this?
Triggers can be used to configure the scheduled jobs.
From the docs
The basic idea of the Trigger is that execution times may be determined based on past execution outcomes or even arbitrary conditions.
Check out this answer for detailed explanation.
In my application, I have set of scheduled tasks which process all users' data and perform various tasks like earning, tax calculations, generate statements for all users. Since these processes need to run for each user, they take a lot of time(many hours) because of large number of users. Data processing for one user is completely independent from another user's, so they can be run in parallel. What are my options here? What are the best practices for doing such large/bulk operations.
We are using J2SE platform with spring, jpa and hibernate.
You should be doing the same via batch.
Since you have mentioned that you were doing with Spring you can consider using Spring Batch.
Spring Batch provides reusable functions that are essential in
processing large volumes of records, including logging/tracing,
transaction management, job processing statistics, job restart, skip,
and resource management. It also provides more advanced technical
services and features that will enable extremely high-volume and high
performance batch jobs through optimization and partitioning
techniques.
Check out the Reference manual on how to implement.
Have a look at the spring documentation for scheduled tasks: http://static.springsource.org/spring/docs/3.0.x/reference/scheduling.html
I find the easiest way to do scheduled tasks is to use #Scheduled annotation, and you can use cron style timing. For each of your users, you could perform your task in a different Thread for each:
#Scheduled(cron="*/5 * * * * MON-FRI")
public void doSomething() {
List<User> users = getUsers();
for(User user: users) {
MyTask task = new MyTask(user);
Thread t = new Thread(task);
t.start();
}
}
Make sure MyTask is a Runnable.
If you have mountains of data and users, you could look at Spring Batch: http://static.springsource.org/spring-batch/
I have a web application that synchronizes with a central database four times per hour. The process usually takes 2 minutes. I would like to run this process as a thread at X:55, X:10, X:25, and X:40 so that the users knows that at X:00, X:15, X:30, and X:45 they have a clean copy of the database. It is just about managing expectations. I have gone through the executor in java.util.concurrent but the scheduling is done with the scheduleAtFixedRate which I believe provides no guarantee about when this is actually run in terms of the hours. I could use a first delay to launch the Runnable so that the first one is close to the launch time and schedule for every 15 minutes but it seems that this would probably diverge in time. Is there an easier way to schedule the thread to run 5 minutes before every quarter hour?
You can let the Runnable schedule its "next run".
Such as,
class Task implements Runnable {
private final ScheduledExecutorService service;
public Task(ScheduledExecutorService service){
this.service = service;
}
public void run(){
try{
//do stuff
}finally{
//Prevent this task from stalling due to RuntimeExceptions.
long untilNextInvocation = //calculate how many ms to next launch
service.schedule(new Task(service),untilNextInvocation,TimeUnit.MILLISECONDS);
}
}
}
Quartz would be a good fit since you're application is web-based. It will provide the fine-grained time based scheduling you need.
Quartz is a full-featured, open source
job scheduling service that can be
integrated with, or used along side
virtually any Java EE or Java SE
application - from the smallest
stand-alone application to the largest
e-commerce system. Quartz can be used
to create simple or complex schedules
for executing tens, hundreds, or even
tens-of-thousands of jobs; jobs whose
tasks are defined as standard Java
components that may executed virtually
anything you may program them to do.
The Quartz Scheduler includes many
enterprise-class features, such as JTA
transactions and clustering.
TimerTask handles this case.
See schedule(TimerTask, Date)
If you don't want to have to keep scheduling the jobs, you may want to look into a job scheduling tool like Quartz.
I have an application that runs in JBoss. I have an incoming web service request that will update an ArrayList. I want to poll this list from another class every 60 seconds. What would be the most efficient way of doing this?
Could anyone point me to a good example?
I would also recommend ScheduledExecutorService, which offers increased flexibility over Timer and TimerTask including the ability to configure the service with multiple threads. This means that if a specific task takes a long time to run it will not prevent other tasks from commencing.
// Create a service with 3 threads.
ScheduledExecutorService execService = Executors.newScheduledThreadPool(3);
// Schedule a task to run every 5 seconds with no initial delay.
execService.scheduleAtFixedRate(new Runnable() {
public void run() {
System.err.println("Hello, World");
}
}, 0L, 5L, TimeUnit.SECONDS);
As abyx posted, Timer and TimerTask are a good lightweight solution to running a class at a certain interval. If you need a heavy duty scheduler, may I suggest Quartz. It is an enterprise level job scheduler. It can easily handle thousands of scheduled jobs. Like I said, this might be overkill for your situation though.
You can use Timer and TimerTask. An example is shown here.
See java.util.Timer. You'll need to start a robot in a separate thread when your app comes up and have it do the polling.
Check the answers to the question "How to run a task daily from Java" for a list of resources related to your problem.
The other answers are basically advising you do your own threads. Nothing wrong with that, but it isn't in conformance with the EJB spec. If that is a problem, you can use JBoss' timer facilities. Here is an example of how to do that.
However, if the EJB spec is at issue, storing state like an ArrayList isn't compliant as well, so if you are just reading some static variable anyway, specifically using a container Timer service is likely overkill.