How do you efficiently repeat an action every x minutes? - java

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.

Related

WSO2 BPS timer event bpmn

DO you know if it's possible to setup some timer event/task to wait for some time for receiving some action? For example, I need to set up some mechanism where I invoke timer task which waits for example for 10 seconds then I will restart checking process.
Thanks,
You can try <pick> It implements the deferred choice workflow pattern, i.e. it can wait for several messages and several timers concurrently. The event that occurs first wins and the contained activity will be executed.
So there is a exists for BPMN which we've used for our needs.

Is Spring's built in Scheduler persistent.?

I have run into a case where I have to use a persistent Scheduler, since I have a web application that can crash or close due to some problems and might lose it job details if this happens . I have tried the following:
Use Quartz scheduler:
I used RAMJobStore first, but since it isn't persistent, it wasn't of much help. Can't setup JDBCJobStore because, this will require huge code changes to my existing code base.
In light of such a scenario,
I have the following queries:
If I use Spring's built in #Schedule annotation will my jobs be persistent..? I don't mind if the jobs get scheduled after the application starts. All I want is the jobs to not lose their details and triggers.?
If not, are there any other alternatives that can be followed , keeping in mind that I need to schedule multiple jobs with my scheduler.?
If yes, how can I achieve this.? My triggers are different each job. For e.g I might have a job that is scheduled at 9AM and another at 8.30AM and so on.
If not a scheduler, then can I have a mechanism to handle this.?
One thing, I found is that the documentation for Quartz isn't very descriptive. I mean it's fine for a top level config, but configuring it on your an application is a pain. This is just a side note. Nothing to do with the question.
Appreciate the help. :)
No, Spring's #Schedule-annotation will typically only instruct Spring at what times a certain task should be scheduled to run within the current VM. As far as I know there is not a context for the execution either. The schedule is static.
I had a similar requirement and created db-scheduler (https://github.com/kagkarlsson/db-scheduler), a simple, persistent and cluster-friendly scheduler. It stores the next execution-time in the database, and triggers execution once it is reached.
A very simple example for a RecurringTask without context could look like this:
final RecurringTask myDailyTask = ComposableTask.recurringTask("my-daily-task", Schedules.daily(LocalTime.of(8, 0)),
() -> System.out.println("Executed!"));
final Scheduler scheduler = Scheduler
.create(dataSource)
.startTasks(myDailyTask)
.threads(5)
.build();
scheduler.start();
It will execute the task named my-daily-task at 08:00 every day. It will be scheduled in the database when the scheduler is first started, unless it already exists in the database.
If you want to schedule an ad-hoc task some time in the future with context, you can use the OneTimeTask:
final OneTimeTask oneTimeTask = ComposableTask.onetimeTask("my-onetime-task",
(taskInstance, context) -> System.out.println("One-time task with identifier "+taskInstance.getId()+" executed!"));
scheduler.scheduleForExecution(LocalDateTime.now().plusDays(1), oneTimeTask.instance("1001"));
See the example above. Any number of tasks can be scheduled, as long as task-name and instanceIdentifier is unique.
#Schedule has nothing to do with the actual executor. The default java executors aren't persistent (maybe there are some app-server specific ones that are), if you want persistence you have to use Quartz for job execution.

Running a time taking process in a separate thread spawning from a servlet filter

There is a servlet filter in my application from which I need to invoke a web service which takes some time to return response and then store the response in session to be used later. I want that by the time this time-taking process takes place my filter should proceed and should continue invoking the other filters too so that the performance is not affected.
So this is what I am thinking of doing inside doFilter(). Create a different thread for this purpose.
log.debug("start filter");
CustomThread ct=new CustomThread();
ct.start(); //invoke web service in run()
log.debug("continuing with filter");
Considering the fact that more that 1000 users will be hitting the application, will this approach work properly. Will this condition fail for some scenario?
Please suggest if I need to take a different route.
The main problem is that you start a new thread each time. This is time consuming, and it can bring the server to its knees if you get many concurrent requests, because you don't have any limit on the number of spawned threads.
I would use a ThreadPoolExecutor instead, which would solve those two problems.
You should use an Executor of some sort rather than worrying about thread management yourself. The Executors class provides a variety of simple ways to create executor instances.

How can I load file into web app through certain periods?

I have next task: I need to load the same file into my web app several times, for example - twice a day! Suppose in that file I have information, that changes, and I need to load this info into my app to change the statistics for example.
How can I load file several times (twice an hour, or twice a day)?
What should I use? Is any algorithm to do that?
I am not allowed to use external libraries like Quartz Scheduler. So I need to do it with Thread and/or Timer. Can anybody give me some example or algorithm how to do it. Where can I create the entry point to my Thread, can I do it in managed bean or I need some sort of filter/listener/servlet. I works with jsf and richFaces. Maybe in this technologies there are some algorithms to solve my problem.
Any ideas?
Thanks very much for help!
If you cannot use a scheduler, then use a servlet and Timer.
In this article it is described how to do that. It's exactly what you need.
Check java.util.Timer, it should be just enough for what you need
how about this:
http://www.quartz-scheduler.org/overview/index.html
I'd use the Quartz Scheduler. I don't know the architecture of your app so I can't really say if Spring configuration or just code configuration is better. You could use a SimpleTrigger, or even a CronTrigger if you want a more expressive scheduling.
I would expose entry point to 'load' functionality as a servlet in your webapp and then use external scheduler (cron on Unix, Scheduled Tasks on Windows) to call that servlet via wget or any other command line http client.
This approach has advantages of not depending on any third party libraries (adding Qurtz just for one task seems like overkill for me) and also has flexibilty of changing schedule without touching your code as well as triggering 'load' manually if desired.
Thanks all for help - I do this task with help of Timer, TimerTask and ServletContextListener:
servletContext = event.getServletContext();
// create the timer and timer task objects
Timer timer = new Timer();
// get a calendar to initialize the start time
Date startTime = Calendar.getInstance().getTime();
List<Company> companies = CompanyUtils.getInstance().getCompanies();
if (companies.size() == 0)
return;
for (int i = 0; i < companies.size(); i++)
{
FileUpdater task = new FileUpdater(companies.get(i).getUrl());
// schedule the task to run hourly
timer.scheduleAtFixedRate(task, startTime, companies.get(i).getUpdatePeriod());
}
// save our timer for later use
servletContext.setAttribute("timer", timer);
Once more thanks!
With best wishes!

Run java thread at specific times

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.

Categories

Resources