java.util.concurrent.ScheduledExecutorService runs very infrequent - java

I have a client application, where a runnable has to run in a fix period. Therefore I use the java.util.concurrent.ScheduledExecutorService as follows:
ScheduledExecutorService scheduledExecutorService =
Executors.newScheduledThreadPool(10);
ScheduledFuture scheduledFuture =
scheduledExecutorService.scheduleAtFixedRate(runnableClass,
period,period,TimeUnit.SECONDS);
As long as the workload is low, the task is scheduled in the defined period, i.e if the client receives no messages from the server. But if the server shoots out messages at full throttle, the runnableClass.run() is not executed on time. I feel like the time between the execution increases exponentially. But the Computer still runs smooth.
All Exceptions are catched inside run() and if I decrease the messages send from the server, the task is scheduled more often.
Why does that happen?
EDIT: The task needs a lot of resources and it is using Rserve to get predictions computed in R. There are probably up to 5000 calls to R in one task.
I made some tests regarding the time of the task. The task was always done in under a second, while the period was between 3 and 20 seconds.

How many threads are you running and how many cores do you have? Can it happen that you serve every request from a different thread, and the context switchings make your app run slower and slower?
Take care not to have much more CPU-bound threads than cores.
(Just a guess, sorry if it's way off)
Also, do you need a scheduled thread pool executor wit core size of 10? Isn't a SingleThreadScheduledExecutor enough for the scheduled task?

Related

Introduce accurate delays in java

I am using my java program to control a motor via Arduino. I plan to introduce the delays in the software itself and not in Arduino. How can I accurately do that since introducing delays using thread.sleep() is very inaccurate? Additionally, I want to pause the delay and upon resume, I want the software to complete the rest of the delay. For example, if I kept a delay for 1000 milliseconds and pause at 700 milliseconds, I want to stop the motor; upon resume, I want to finish the rest of the 300 milliseconds. How efficient it would be if I use a while loop till the System.currentTimeMillis() reaches a specific amount of time?
Make use of ScheduledThreadPoolExecutor. ScheduledExecutorService is an executor service that allows you to schedule future and recurring asynchronous tasks in Java.
It has been observed that long/ recurring tasks executed using ScheduledExecutorService can result in Memory Leaks. Since Java 7, ScheduledThreadPoolExecutor exposed a new method setRemoveOnCancelPolicy. Make sure this flag is set, as a precautionary measure.
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
// Explicitly call setRemoveOnCancelPolicy on the instance
executor.setRemoveOnCancelPolicy(true);
As per javaDoc, setRemoveOnCancelPolicy sets the policy on whether cancelled tasks should be immediately
removed from the work queue at time of cancellation. This value is by
default false

Does multithreading cause each task to take longer?

I'm new to multithreading... multithreading is used to improve performance, however how can this be so if the processor is already working as fast as it can for a single thread?
To explain:
In a single threaded environment User A starts a task which takes 1 second - the task is completed in 1 second.
User B starts the same task a fraction of a second later and has to wait for user A, therefore user Bs task completes in almost 2 seconds. Now, if this was a multithreaded environment would both tasks not be run similtaeously causing both to take 2 seconds? ...e.g. part of task A done, then part of task B, then part of task A again, then part of task B, ...till eventually both tasks complete in around two seconds?
Is it only faster if there is more than one processor? Or should multithreading be reserved for when there is a big task being dealt with and smaller tasks need to pop in and out of existence during this time?
If the task is 100% CPU bound, and you have only one CPU core, then multithreading will make things slower. If you have more than one CPU core, clearly you can allocate as many threads as you have cores to improve performance. If the tasks interact with anything external (I/O) then multithreading can increase performance to a point. While one thread is waiting for I/O to complete, other threads can be performing CPU-based processing.
The classic example is a program that does computation and also displays a GUI. You update the GUI on one thread (the event thread) and do all processing on other "background" threads. The event thread does nothing but handle user interactions. If you don't do this then when a user-requested operation takes appreciable time the GUI stops responding. In this situation, you would run multithreaded even on a single-core system.
How to tune an application's use of threads depends on a lot of factors and could take up an entire textbook.
Ok now consider that Task A of your's needs a particular resource (ex a network file or a user input) to complete its work. Now say the resource needed by the Task A is not currently available so what happens next in a single threaded environment is that Task A has control of the CPU so it'll wait for the resource to be available and at this time the CPU will be idle which means we're wasting an important resource i.e, the CPU time while waiting for some other resource. But if the Task A has been implemented in multithreaded environment when Task A waits for the resource, it(Task A thread) gets suspended till the resource become available and the CPU time can be used efficiently to execute other tasks. Hope this helps :)

ScheduledThreadPoolExecutor - single task/thread running often or multiple threads running less often

I'm trying to set up a job that will run every x minutes/seconds/milliseconds/whatever and poll an Amazon SQS queue for messages to process. My question is what the best approach would be for this. Should I create a ScheduledThreadPoolExecutor with x number of threads and schedule a single task with scheduleAtFixedRate method and just run it very often (like 10 ms) so that multiple threads will be used when needed, or, as I am proposing to colleagues, create a ScheduledThreadPoolExecutor with x number of threads and then create multiple scheduled tasks at slightly offset intervals but running less often. This to me sounds like how the STPE was meant to be used.
Typically I use Spring/Quartz for this type of thing but that's out of at this point.
So what are your thoughts?
I recommend that you use long polling on SQS, which makes your ReceiveMessage calls behave more like calls to take on a BlockingQueue (which means that you won't need to use a scheduled task to poll from the queue - you just need a single thread that polls in an infinite loop, retrying if the connection times out)
Well it depends on the frequency of tasks. If you just have to poll on timely interval and the interval is not very small, then ScheduledThreadPoolExecutor with scheduleAtFixedRate is a good alternative.
Else I will recommend using netty's HashedWheelTimer. Under heavy tasks it gives the best performance. Akka and play uses this for scheduling. This is because STPE for every task adding takes O(log(n)) where as HWT takes O(1).
If you have to use STPE, I will recommend one task at a rate else it results in excess resource.
Long Polling is like a blocking queue only for a max of 20 seconds after which the call returns. Long polling is sufficient if that is the max delay required between poll cycles. Beyond that you will need a scheduledExector.
The number of threads really depends on how fast you can process the received messages. If you can process the message really fast you need only a single thread. I have a setup as follows
SingleThreadScheduledExecutor with scheduleWithFixedDelay executes 5 mins after the previous completion
In each execution messages are retrieved in batch from SQS till there are no more messages to process (remember each batch receive a max of 10 messages).
The messages are processed and then deleted from queue.
For my scenario single thread is sufficient. If the backlog is increasing (for example, a network operation is required for each message which may involve waits), you might want to use multiple threads. If one processing node become resource constrained you could always start another instance (EC2 perhaps) to add more capacity.

Force regular execution of periodic task within Java application

ScheduledExecutorService seems to have the problem that if it can't get a free thread the periodic task will happen with delay. Unfortunately for me, the periodic task it's assigned to really does need to happen fairly on schedule. At present it's scheduled for once per minute but sometimes due to the application being busy with other things (I assume this is why) it fails to make it within five minutes, and five minutes happens to be the "major production bugs" threshold.
How to force this via prioritizing or otherwise controlling the thread balancer?
If your ScheduledExecutorService is used for other tasks or if your task sometimes takes more than 1 minute to run, you can simply increase the number of threads available in your ScheduledExecutorService. So if one task has not finished running, the executor will still be able to run a new one.
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(10);
(I picked 10 randomly - if you run your task every minute and it can run for up to 5 minutes, that leaves you some margin for error)

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