TaskScheduler queue tasks spring - java

This is more like a concept questions. I have a process that when receives a request throught REST made by another process it schedules jobs. each time it's called, schedule a new job.
It's OK here. My question is, what happens if for some reason a job can't be executed? The next time it has to be executed, but if it never happens? Could tasks be queued and then make me have a problem with memory?
Thanks

If the task is not accepted you should get a TaskRejectedException that you can handle. If the task is accepted it should eventually run. If you schedule tasks far off in the future and keep adding more tasks or if the system is overloaded and can't process the tasks fast enough of course you can run out of memory eventually. However, a task is not likely to consume that much memory, so in that case you will probably have other more urgent problems first!

Related

Stop UI-method until Async task is finished

Sorry for me poor english.
i am messing about with a java class that needs to do UI-work. but the UI-work needs to wait for an async task. The asyncTask retrieves api soap from internet. Once api is retrieved it is set to global jsonResponseBody. Then UI-method then uses jsonResponseBody to do UI-stuff.
In my now code, I use while-loop to stop from moving on before jsonResponseBody is ready. Is while-loop best idea for me? I think maybe while-loop will slow down main-thread, no?
//Pre-async task stuff is run
connectDbAsync(db,sqlQuery); //This will set jsonResponseBody sooner or later
while(jsonResponseBody == null){
//Do nothing, just wait
}
//Post-async task stuff which uses jsonResponseBody
When performing asynchronous tasks in Java there are several ways to handle output. One way as you discovered, is to use a loop to block code execution until the task completes. I personally like to use a thread pool and Future objects to wait on my threads to complete. There are some advantages and disadvantages to both approaches, however in your case, your while loop should not slow your main thread because it only runs for a finite period of time and runs immediately after you start executing your asynchronous task.
That said, the benefit of an asynchronous task is that it can do its thing while your code is doing something else. If you MUST wait on the asynchronous task to complete before continuing on in your method, then the task could be done synchronously instead and you wouldn't need the loop to pause execution.
Example blocking code that waits on network poll of multiple "sites" before continuing execution. This shows the benefit of asynchronous tasks/multithreading when it comes to doing multiple things at one time:
//Invoke run method on each site simultaneously, store results in a list
List<Future<Site>> futures=threadmaker.invokeAll(active_sites.stream().map(TAG_SCANNER::new).collect(Collectors.toList()));
List<Site> alarm_sites = new ArrayList<>();
//Now fetch all the results serially
for(Future<Site> result: futures){
//SOUND THE ALARMS
alarm_sites.add(result.get());
}
// Continue synchronous method execution
You might have a look at java Future. You can use it to launch some code asynchronously but you get a handle to it and so you can check if it is finished (Future.isDone()) or block until it is finished: Future.get()

Schedule periodic tasks in Java, avoid creating new threads until necessary (like CachedThreadPool)

I have a number of tasks that I would like to execute periodically at different rates for most tasks. Some of the tasks may be scheduled for simultaneous execution though. Also, a task may need to start executing while another is currently executing.
I would also like to customize each task by setting an object for it, on which the task will operate while it is being executed.
Usually, the tasks will execute in periods of 2 to 30 minutes and will take around 4-5 seconds, sometimes up to 30 seconds when they are executed.
I've found Executors.newSingleThreadedScheduledExecutor(ThreadFactory) to be almost exactly what I want, except that it might cause me problems if a new task happens to be scheduled for execution while another is already executing. This is due to the fact that the Executor is backed up by a single execution thread.
The alternative is to use Executors.newScheduledThreadPool(corePoolSize, ThreadFactory), but this requires me to create a number of threads in a pool. I would like to avoid creating threads until it is necessary, for instance if I have two or more tasks that happen to need parallell executing due to their colliding execution schedules.
For the case above, the Executors.newCachedThreadPool(ThreadFactory) appears to do what I want, but then I can't schedule my tasks. A combination of both cached and scheduled executors would be best I think, but I am unable to find something like that in Java.
What would be the best way to implement the above do you think?
Isn't ScheduledThreadPoolExecutor.ScheduledThreadPoolExecutor(int):
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(0);
what you need? 0 is the corePoolSize:
corePoolSize - the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set
I guess you will not able to do that with ScheduledExecutor, because it uses DelayedWorkQueue where as newCachedThreadPool uses ThreadPoolExecutor SynchronousQueue as a work queue.
So you can not change implementation of ScheduledThreadPoolExecutor to act like that.

Help with a task scheduling algorithm

I am working on an application in which thousands of tasks associated
with hundreds of devices, each task requiring, < 5ms to begin execution, and
taking on average 100ms to complete.
The conditions are as such:
Each device can only process a single
task at a time, e.g., one task must finish running on its assigned
device prior to subsequent task's being processeed.
The scheduler should be efficient. Currently, processing a given device's
work queue takes longer than the sum of it's tasks.
Here is basic description of the current implementation:
Each device contains a work queue which is filled with tasks associated with
that device.
When a task is enqueued, that device's work queue is placed into a
global run queue (a queue of queue's). The global run queue is consumed by a worker thread
which dequeue's the device's task objects, processes one, then places
the device queue at the back of the global run queue. When that given device
has been dequeued again, the worker thread checks to see if the task has completed,
if so, the next task is executed. This process continues, until all device queues
have been depleted of tasks in the global runqueue.
Any suggestions for improvements? Have I stated this clearly? If not, please let me know, and I'll do my best to clarify.
Thanks for taking the time to look this over. Regards.
How about something like the ExecutorCompletionService together with a ThreadPoolExecutor. This gives you callback on completion, which you can use to submit subsequent jobs, and a managed threadpool of executors, which you can tweak to improve throughput.
I suggest you run your code through a profiler to see which threads are currently blocking (sounds like it will be your producer device threads). I can recommend YourKit Java Profiler, however its not free.
The problem with your design is that only one task is run at a time, which means that any device is idle while any other device is in use.
Since there are hundreds of devices, it would probably not be a good idea to assign a thread to each of these devices, but a thread pool could very well be used.

ScheduledThreadPoolExecutor and corePoolSize 0?

I'd like to have a ScheduledThreadPoolExecutor which also stops the last thread if there is no work to do, and creates (and keeps threads alive for some time) if there are new tasks. But once there is no more work to do, it should again discard all threads.
I naivly created it as new ScheduledThreadPoolExecutor(0) but as a consequence, no thread is ever created, nor any scheduled task is ever executed.
Can anybody tell me if I can achieve my goal without writing my own wrapper around the ScheduledThreadpoolExecutor?
Thanks in advance!
Actually you can do it, but its non-obvious:
Create a new ScheduledThreadPoolExecutor
In the constructor set the core threads to the maximum number of threads you want
set the keepAliveTime of the executor
and at last, allow the core threads to timeout
m_Executor = new ScheduledThreadPoolExecutor ( 16,null );
m_Executor.setKeepAliveTime ( 5, TimeUnit.SECONDS );
m_Executor.allowCoreThreadTimeOut ( true );
This works only with Java 6 though
I suspect that nothing provided in java.util.concurrent will do this for you, just because if you need a scheduled execution service, then you often have recurring tasks to perform. If you have a recurring task, then it usually makes more sense to just keep the same thread around and use it for the next recurrence of the task, rather than tearing down your thread and having to build a new one at the next recurrence.
Of course, a scheduled executor could be used for inserting delays between non-recurring tasks, or it could be used in cases where resources are so scarce and recurrence is so infrequent that it makes sense to tear down all your threads until new work arrives. So, I can see cases where your proposal would definitely make sense.
To implement this, I would consider trying to wrap a cached thread pool from Executors.newCachedThreadPool together with a single-threaded scheduled executor service (i.e. new ScheduledThreadPoolExecutor(1)). Tasks could be scheduled via the scheduled executor service, but the scheduled tasks would be wrapped in such a way that rather than having your single-threaded scheduled executor execute them, the single-threaded executor would hand them over to the cached thread pool for actual execution.
That compromise would give you a maximum of one thread running when there is absolutely no work to do, and it would give you as many threads as you need (within the limits of your system, of course) when there is lots of work to do.
Reading the ThreadPoolExecutor javadocs might suggest that Alex V's solution is okay. However, doing so will result in unnecessarily creating and destroying threads, nothing like a cashed thread-pool. The ScheduledThreadPool is not designed to work with a variable number of threads. Having looked at the source, I'm sure you'll end up spawning a new thread almost every time you submit a task. Joe's solution should work even if you are ONLY submitting delayed tasks.
PS. I'd monitor your threads to make sure your not wasting resources in your current implementation.
This problem is a known bug in ScheduledThreadPoolExecutor (Bug ID 7091003) and has been fixed in Java 7u4. Though looking at the patch, the fix is that "at least one thread is started even if corePoolSize is 0."

handling sleep in java scheduled executor service

I have a sort of complex problem like below.
- we have a real time system with large number threads requirement. In order to optimize the performance, we are thinking of following design.
create a thread pool executor with max number of threads
each thread is used to create scheduled executor service.
now the tasks are being assigned to these executor services evenly based on load
BUT the biggest problem is, if one of the task in the queue contains a sleep (for few secs), it blocks the corresponding Schedule executor service thread for that duration and subsequently all the following tasks in that queue.
In this regard, please suggest me how to suspend the execution of the task with sleep OR overriding the sleep somehow and rejoin/schedule the task again to the queue.
Thanks in advance
Seshu
Assuming I understand your question, your Schedule Executor service threads have a deadline requirement, but the actual workers can sleep for an unknown length of time, possibly throwing off the timing of the Schedule Executors. From your description I'm guessing what you want is for a task that needs to sleep to actually stop, save progress information and then requeue itself for the remainder of the work to be rescheduled at some future time. You'd have to build this into your application architecture.
Alternatively, you could have the scheduler threads launch the worker tasks in their own separate threads, letting them sleep as necessary, with one scheduler thread collecting all the worker terminations.
To get a better answer you're going to have to provide more information about what you're trying to accomplish.
Tasks which sleep are inherently unfriendly for running in any kind of bounded thread pool. The sleep is explicitly telling the thread that it must do nothing for a period of time.
If possible, split the task into 2 (or more parts), eliminating the sleep completely. Get the first half-task to schedule the second task with an appropriate delay.
Failing that, you could consider increasing the size of your thread pool somewhat - either setting a much larger cap to its size, or possibly even eliminating the cap altogether (not recommended for a server than might end up with many clients).
Alternatively, move the tasks with sleep statements in them into their own Scheduled executor. Then, they'll delay each other, but better-behaved tasks, with no wait statements in them, will get preferential treatment.

Categories