scheduleAtFixedRate not starting the task at specified delay - java

I am using SchedulerExecuterService to execute a task after specified delay and at given intervals.
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(taskThread,60 ,120 ,TimeUnit.SECONDS);
What happening is first time taskThread is not starting after delay of 60 sec, it is started after delay of more than 60 secs. Whereas the next executions started at correct intervals of 120 secs(not exactly 120 secs but there is a very minute delay which can be ignored).
My query is why the first execution is delayed for more than 60 secs? Since the task is executed by a thread, Does the start up time depends on the thread priority?
How can I make it run at exact delay of 60 secs? What about Quartz library? Will this library solve my purpose(run the job at specific time without any delay)?
Thanks in advance.

Startup of a job depends on the scheduled time and the amount of threads available - if there are none available, it can be delayed. However, further executions will start at a scheduled time (delay + n * period) - which is takes place in your case.
Start will happen approximately at a scheduled time, I doubt there are real-time guarantees for this, it depends on the underlying OS. You could try changing a thread priority for a thread in this thread pool. This could help, but it won't give you a guarantee that it would work out in different environment.
You could also make sure you run a single task for a fixed thread pool of a single thread you use. Or try increasing the thread amount.

T.b.h. the delay you are seeing is unlikely to be ScheduledExecutorService's fault. Starting a thread won't take a second unless your machine is ridiculously overloaded, and I think the thread will get initialised up-front anyways if you use a fixed size thread pool.
I'm guessing it's the initialisation of your own tasks. I don't know what you are doing in your task, but getting the resource ready (starting DB connection pools) etc. can amount to significant time.
If you want you can test with a trivial task (like writing "hello" on the console) to see. And then you can measure each part of your task to see what's taking long. Once you have that you can think of ways to "warm" your system to prevent the delay.

Related

Scheduled Thread Pool with timeout - possible approaches

I know #Synchronized in spring-boot (spring boot is my base technology). However, it can't allow me to set timeout for scheduled funtion.
I heard about java 8 concurrent features, but I am not sure if it can help me.
To sum up:
Periodical (at each 0.5s) execution thread from some limited thread pool and possibility of timeout this scheduled tread.
Any ideas ?
Consider ScheduledThreadPoolExecutor
scheduleAtFixedRate() lets you schedule tasks to be executed after a specified delay and executed again based on the period you specified.
scheduleWithFixedDelay() lets you create tasks that will be executed after the initial delay and then subsequently with provided delay between the termination of last execution and start of another execution.

Does Thread.sleep() make the execution to cease for accurate an interval

Here is my code
try{
System.out.println("Before");
thread.sleep(10000);//sleep for 10000 ms
System.out.println("After");
}
catch(ItrerruptedException ie){
//If this thread was intrrupted by nother thread
}
I just want to know whether the thread will sleep for exaclty 10 seconds and then print After or there is some delay?
From the javadocs: Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. Which means it will sleep for at least 10 seconds. It may sleep longer if the scheduler decides to not let it run after the 10 seconds is over.
Which may happen if more concurrent threads are in the runnable pool at the same time.
A non realtime scheduler won't guarantee timing.
If you are doing some kind of hardware communication that really relies on timing, you should probably use RTSJ.
If you are doing something each x milliseconds, you could use a TimeTask that will perform slightly better.
It will sleep for at least 10 seconds, and wake shortly after (unless interrupted). How soon after depends on the OS and the load on the machine.
It's more or less random because your OS task scheduler is usually not required to give your process all the attention it wants. Usually, you will not be able to sleep for very small amounts of time (for example, Thread.sleep(5) might resume your process later than 5 ms after the call), but as you increase the sleep time, the relative precision increases.
If you can tolerate some leeway, Thread.sleep(10000) will usually sleep for an amount of time that's close enough to 10 seconds.
I would say unless you have lots of threads running it's pretty close to exact. If you have several threads then it's a competition.
The overhead of the thread from sleep to running is very low.

Executing some code after a specific amount of time

I need to execute an action after a specific amount of time (for example 30 minutes after the app started up, if the app is still up).
What are my options and will it necessary means there's going to be one thread "lost" waiting for the 30 minutes to pass by?
Ideally, at program startup, I'd like to do something like the following (simplified on purpose) and then don't have to think about it anymore:
doIfStillUp( 30, new Runnable() {
....
});
So how should I go about implementing doIfStillUp(...)?
Should I use a TimerTask? The Executor framework?
Most importantly (it's for understanding purpose): does this mean there's going to be one thread lost idling for basically nothing during 30 minutes?
If there's going to be one thread "doing nothing", is this an issue? What if there are 10 000 threads (I'm being facetious here) "doing nothing"?
Note that I'm trying to understand the "big picture", not to solve a particular problem.
The Executor framework is a reasonable choice.
There's a schedule method that just takes a runnable and a delay time.
schedule(Runnable command,
long delay,
TimeUnit unit)
That's pretty straightforward. There won't necessarily be a thread blocked waiting on your task. You could use a ScheduledThreadPoolExecutor, as linked above that keeps X threads ready to run scheduled tasks.
You can imagine a data structure that holds the time at which a task should be run. A single thread can watch or set up these delays and can potentially watch thousands of them in a single thread. When the first time expires it'll run the task. Potentially using its own thread, potentially using 1 of X in the thread pool. When a new task is added or an existing task is finished it'll wait for the earliest time to arrive and then start the whole process again.
You should use a Timer. Its javadoc answers all your questions.
One thread is used for every timer, but the timer executes several tasks, sequentially. The timer tasks should be very short. If they aren't, consider using several timers.
Of course, the timer thread will be idle if it doesn't have any task to execute. An idle thread doesn't consume anything (or nearly anything), so I wouldn't worry about it. Anyway, you don't have many choices. 10000 threads doing nothing would of course be an issue, but that would mean that you instantiated one timer per task, which is wrong.
You can schedule task on java.util.Timer. For all timer tasks single timer thread will be created by java.util.Timer.
The builtin java timer is the straight away solution: http://download.oracle.com/javase/1,5.0/docs/api/java/util/Timer.html#schedule(java.util.TimerTask, long)

Starting a task in hazelcast lasts > 2 sec sometimes

we are using Hazelcast distributed tasks a lot and realized, that sometimes just starting a task lasts > 2 sec, even before the task itself is executed. We did this on a single machine; that is, no network overhead. The task executed itself has just a single line of code in its call() method (we placed a System.currentTimeMillis() at beginning and end) stores the passed argument "client" in its constructor call - nothing else.
Task is started as follows:
FutureTask<Member> task = new DistributedTask<Member>(new NotifyWaitingClientTask(client),
theId);
ExecutorService executorService = hazelcastInstance.getExecutorService();
executorService.execute(task);
...
task.get();
Question is: is this a usual time? We expected rather milliseconds on local machines.
This is not normal unless you have two many tasks that take too much time and the Executor threads are already occupied. So the task will not start until there is an available thread to execute and you'll see that latency.
If this is not the case, can you come up with the code that we can run and reproduce the issue.
Fuad
Hazelcast

ThreadPoolExecutor - ArrayBlockingQueue ... to wait before it removes an element form the Queue

I am trying to Tune a thread which does the following:
A thread pool with just 1 thread [CorePoolSize =0, maxPoolSize = 1]
The Queue used is a ArrayBlockingQueue
Quesize = 20
BackGround:
The thread tries to read a request and perform an operation on it.
HOWEVER, eventually the requests have increased so much that the thread is always busy and consume 1 CPU which makes it a resource hog.
What I want to do it , instead sample the requests at intervals and process them . Other requests can be safely ignored.
What I would have to do is put a sleep in "operation" function so that for each task the thread sleeps for sometime and releases the CPU.
Quesiton:
However , I was wondering if there is a way to use a queue which basically itself sleeps for sometime before it reads the next element. This would be ideal since sleeping a task in the middle of execution and keeping the execution incomplete just doesn't sound the best to me.
Please let me know if you have any other suggestions as well for the tasks
Thanks.
Edit:
I have added a follow-up question here
corrected the maxpool size to be 1 [written in a haste] .. thanks tim for pointing it out.
No, you can't make the thread sleep while it's in the pool. If there's a task in the queue, it will be executed.
Pausing within a queued task is the only way to force the thread to be idle in spite of queued tasks. Now, the "sleep" doesn't have to be in the same task as the "work"—you could queue a separate rest task after each real task, which might make for a cleaner implementation. More importantly, if the work is a Callable that returns a result, separating into two tasks will allow you to obtain the result as soon as possible.
As a refinement, rather than sleeping for a fixed interval between every task, you could "throttle" execution to a specified rate. This would allow you to avoid waiting unnecessarily between tasks, yet avoid executing too many tasks within a specified time interval. You can read another answer of mine for a simple way to implement this with a DelayQueue.
You could subclass ThreadPool and override beforeExecute to sleep for some time:
#Overrides
protected void beforeExecute(Thread t,
Runnable r){
try{
Thread.sleep( millis); // will sleep the correct thread, see JavaDoc
}
catch (InterruptedException e){}
}
But see AngerClown's comment about artificially slowing down the queue probably not being a good idea.
This might not work for you, but you could try setting the executor's thread priority to low.
Essentially, create the ThreadPoolExecutor with a custom ThreadFactory. Have the ThreadFactory.newThread() method return Threads with a priority of Thread.MIN_PRIORITY. This will cause the executor service you use to only be scheduled if there is an available core to run it.
The implication: On a system that strictly uses time slicing, you will only be given a time slice to execute if there is no other Thread in the entire program with a greater priority asking to be scheduled. Depending on how busy your application really is, you might get scheduled every once in awhile, or you might not be scheduled at all.
The reason the thread is consuming 100% CPU is because it is given more work than it can process. Adding a delay between tasks is not going to fix this problem. It is just make things worse.
Instead you should look at WHY your tasks are consuming so much CPU e.g. with a profiler and change them so that consume less CPU until you find that your thread can keep up and it no longer consumes 100% cpu.

Categories

Resources