I have 5-6 threads running in my application. Each thread has an infinite loop and is designed to do some job. After completing the job, I have added a sleep for few seconds/minutes.
The requirement is such that, a particular job should be executed every minute. So what I did was
What I observed from the logs is:
The problem is that as there are multiple threads being executed simulatenously. So what by the time my thread gets the processor 2-3 minutes have already passed and on top of that I have added a sleep for 1 minute. So the difference that is visible between executions of job A is around 3-4 minutes. Can you please suggest some approach if this is technically possible to achieve a timing of approx 1 minute between job executions?
Few questions and approaches I have in mind regarding multithreading, if anyone of you can answer
1) How frequently the processor is switched between threads? Is it done every millisecond, every second, or every minute or how frequently it is done?
2) Raising the priority of my thread would improve the timing, but that can affect the processing of other threads. What do you think?
If the OS does the time slicing then its ok, else if processor is allocated to a thread, it will not reliquish the control of processor till the time
a) It completes it job
b) It releases the processor by yield/sleep
If you want to make sure a task is run at certain intervals, either use a java.util.Timer (if all tasks can be run in one thread, they are pretty quick tasks, and/or your tasks can be offset from their scheduled time without causing a problem) or ScheduledThreadPoolExecutor (if you need to allow long running tasks and can not block other tasks from executing on time).
Joined: Dec 05, 2008
thanks steve for visiting my post and taking out time to reply.
but timer class also uses threads internally..isn't it?
do you have insight about the functioning of timer class?
changing the design at this point is not at all possible for me.
i am looking for alternatives and will choose the approach which will have minimal code change. what do you think if i change the priority of my thread to maximum ?
Timer does use threads, but fewer of them - all tasks are run on the same thread and the timing is maintained on another thread.
There needs to be code change either way. What happens if your thread gets interrupted before the scheduled time? You ignore the exception then do the task early. Is that acceptable? Setting the thread priority can work but you still are at the mercy of Thread.sleep(). I would use the built-in scheduling tools when they necessary as they are likely to do a lot more work to ensure timely execution than anything I write. So how much code change? I would modify the class A you have below to this:
Note that I took out the loop and the sleeping. Then I when I am creating the tasks to run, I would do this:
Joined: Dec 05, 2008
that is really wonderful steve. I will definitely learn more about these classes. But at this point i would also like to learn more about how time slicing happens. I believe thread switching must be done by OS every few milliseconds, what I am surprised that how come my thread turn didnt come for continous 180 seconds.
I know what i am trying to ask is highly unpredictable and can vary from OS to OS, but still i will be interested to know what do you think about this?
So you know it is unpredictable and variable dependent on OS, CPU, and other factors. Add to that my person considerations:
- Fewer threads are better, because it reduces the number of slices required, therefore extending the time for each slice provided to each task
- If all your threads are 'high priority' then none of them are (they are all competing for the same slices at the same priority). So keep your prioritizing strict.
- Since you know it is unpredictable, variable, dependent or many things, and not defined, don't try to study, deal with, predict, or plan on anything related to time slicing. Let the OS handle that.
In your case, I don't necessarily believe your problem is all about time slicing from the CPU. You don't show the code that is actually being run (no you don't need to show that), but there are a number of other things that can control when your thread can run. Things like synchronized locks, resource connections, or file or disk access. Many of these things allow only limited or exclusive access to their respective resources. So as one thread acquires access to the resource other threads can't and have to wait until it is available. So you should look at your code, see what resources you are using, and see if they allow access to multiple threads, or if it even makes sense to try concurrent access.
Joined: Dec 05, 2008
I tried simulating the problem in a sample POC type project. I am able to simulate the delay upto 3 seconds. But a delay of 3 minutes makes me wonder
Here is the POC that I had developed, which looks similar to what is being done in my project.
The output on Windows OS is:
Thu Jun 28 10:40:36 GMT+05:30 2012 : D = 1
Thu Jun 28 10:41:39 GMT+05:30 2012 : D = 2
Thu Jun 28 10:42:42 GMT+05:30 2012 : D = 3
Thu Jun 28 10:43:45 GMT+05:30 2012 : D = 4
Thu Jun 28 10:44:48 GMT+05:30 2012 : D = 5
Thu Jun 28 10:45:51 GMT+05:30 2012 : D = 6
BUILD SUCCESSFUL (total time: 6 minutes 21 seconds)
A similar pattern appears with a time difference of 1 minute 3 second on actual production system as well (which is a unix box). Can you help me tweaking this program, so that actual 3 minute gap can be reproduced between executions.
I know and understand that its very unpredictable thing, but still 3 minutes time difference is something which makes me think again and again.
You should really consider using a timer for this if this timing is very important.
Those statistics you are collecting are very volatile. They could even be affected by the behaviors of other programs running on the same operating system as the JVM.
The right tool for the right job.
Yogesh Gandhi wrote:A similar pattern appears with a time difference of 1 minute 3 second on actual production system as well (which is a unix box).
This is by your design in the above code. You have a process which works for 3 seconds. You have a sleep for 1 minute. The process is repeated every 1 minute 3 seconds. The code is behaving exactly as written and is NOT being affected by time slicing.
Can you help me tweaking this program, so that actual 3 minute gap can be reproduced between executions.
I did in my previous posts.
If you really want to write the code yourself, and ignore everything that has been said, read this (and either ignore it or not):
If your task takes 3 seconds, and you want the task to repeat precisely 60 seconds apart, how long should you wait for the next cycle to begin after the task completes?