In Timer.schedule(TimerTask task, long delay), it says it will throw if delay is negative, but doesn't say anything about if delay is zero. What will happen? I tried on openjdk and it ran instantly. Is this behavior specified somewhere else, or is it undefined (e.g it means infinite on other implementations, or some implementations will do infinite sometimes and instant sometimes)?
From the Java SE7 documentation:
If delay is less than or equal to zero, the timer fires as soon as it is started
So the result you got is the expected behavior.
I believe a Timer in java is a Thread with a task queue. Items are ordered in the task queue by when they are supposed to fire. Tasks with a delay of 0 are supposed to fire immediately and thus go to top of queue. I believe the behavior you are seeing is expected and should be consistent cross platform and across different jdks
Related
Timer.cancel(): Cancels the task.
Timer.purge(): Remove all cancelled tasks from this timer's task queue.
What would happen when I would not use purge() here? What would happen when the timer's task queue got filled?
Nothing will change as to the actual Timer behaviour unless you have an ungodly number of timers going on. The cancel method does stop the timer running, but the program will still keep a reference to the timer even after its been cancelled, and so the memory it used will still be in use. The purge method allows Java to mark the timer references for garbage collection, allowing the memory they are using to be used for something else.
Most programs will not need to use the purge method, its just there for programs that will use a lot of timers, either many in a short burst, or if a program is going to be running for many days at a time.
I want to schedule an event to happen at a particular time, regardless of whether the computer suspends in the meanwhile. If computer is suspended when the event should have occurred, I want it to be scheduled immediately on resume.
I tried two ways: a thread with a sleep(), and a Swing Timer. Both these methods rely on a timed delay, and both suffer the same problem in that the delay countdown is suspended when the computer suspends, and continues only when the computer resumes, so the event occurs at (original delay + time suspended).
I then guessed that what I should be doing is to use a (util) Timer with a target Date, as this specifies a point in time, like so:
Date targetDate = new Date(System.currentTimeMillis() + (60 * 1000)); // in 1 min
Timer eventTimer = new Timer();
eventTimer.schedule(eventThread, targetDate);
Unfortunately this suffers in exactly the same way.
I did also look at the ScheduledExecutorService (although overkill for this application I thought) but it explicitly uses delays, so I assumed it would suffer the same problem.
Is what I want to do possible?
the delay countdown is suspended
No, this is not really what happens. Otherwise it would mean the system time would be wrong on resume!
Is what I want to do possible?
Here is a solution:
have one task handle all the scheduling, which runs, say, every second;
in a task to be executed, record the time, make the class of your task Comparable against the expected execution time;
put all these tasks in a PriorityQueue (or even a PriorityBlockingQueue);
when the scheduling task wakes up, peek the tasks; if the expected execution time is less than, or equal, to the current time, dequeue it and execute it; repeat until the peeked task has an expected execution time greater than the current time.
This will not make for "immediate execution upon resume", but close to.
Things are even weirder. I have a program that refreshes data on an hourly basis, using java.util.Timer and a suitable TimerTask. With openSuse up to version 13.1 that program worked as required - when due to a suspend the real time exceeded the cycle, the task was called "immediately" after the resume.
Running the same program with the same jvm (1.8.0_40-b10) and the same Linux kernel (3.14.24), but with openSuse 13.2, the task is not called on resume but only after the period has expired in wake mode.
I have solved this problem by calling the task via a function key if the current time exceeds the scheduled time and resynchronizing the task if necessary. That's a nuisance but acceptable because the resume is anyway done via a key stroke.
I have two ExecutorServices, one to hold producers and the other one to hold consumers. I'm using the awaitTermination method, which is blocking and needs a timeout parameter. But I want to wait on both ExecutorServices with the same timeout. As the awaitTermination call is blocking, I can't do:
this.producersExecutorService.awaitTermination(4, TimeUnit.HOURS);
this.consumersExecutorService.awaitTermination(4, TimeUnit.HOURS);
Because that would, eventually, wait for a total of 8 hours. What should I do?
If you're waiting for both of them, just await either of them with a timeout of 4 hours, then await the other one with however much time is remaining. How you determine that is up to you - I'd probably work out the desired end time based on the current time before the first call to awaitTermination, and then work out the remaining time based on the difference between that and the current time.
It's not clear from the documentation what happens if you pass in a negative time - you should probably investigate that, and potentially take precautions (e.g. if the first call finishes at exactly the timeout, and then you end up computing the second timeout a millisecond later).
Inline Java IDE hint states, "Invoking Thread.sleep in loop can cause performance problems." I can find no elucidation elsewhere in the docs re. this statement.
Why? How? What other method might there be to delay execution of a thread?
It is not that Thread.sleep in a loop itself is a performance problem, but it is usually a hint that you are doing something wrong.
while(! goodToGoOnNow()) {
Thread.sleep(1000);
}
Use Thread.sleep only if you want to suspend your thread for a certain amount of time. Do not use it if you want to wait for a certain condition.
For this situation, you should use wait/notify instead or some of the constructs in the concurrency utils packages.
Polling with Thread.sleep should be used only when waiting for conditions external to the current JVM (for example waiting until another process has written a file).
It depends on whether the wait is dependent on another thread completing work, in which case you should use guarded blocks, or high level concurrency classes introduced in Java 1.6. I recently had to fix some CircularByteBuffer code that used Thread sleeps instead of guarded blocks. With the previous method, there was no way to ensure proper concurrency. If you just want the thread to sleep as a game might, in the core game loop to pause execution for a certain amount of time so that over threads have good period in which to execute, Thread.sleep(..) is perfectly fine.
It depends on why you're putting it to sleep and how often you run it.
I can think of several alternatives that could apply in different situations:
Let the thread die and start a new one later (creating threads can be expensive too)
Use Thread.join() to wait for another thread to die
Use Thread.yield() to allow another thread to run
Let the thread run but set it to a lower priority
Use wait() and notify()
http://www.jsresources.org/faq_performance.html
1.6. What precision can I expect from Thread.sleep()?
The fundamental problem with short sleeps is that a call to sleep finishes the current scheduling time slice. Only after all other threads/process finished, the call can return.
For the Sun JDK, Thread.sleep(1) is reported to be quite precise on Windows. For Linux, it depends on the timer interrupt of the kernel. If the kernel is compiled with HZ=1000 (the default on alpha), the precision is reported to be good. For HZ=100 (the default on x86) it typically sleeps for 20 ms.
Using Thread.sleep(millis, nanos) doesn't improve the results. In the Sun JDK, the nanosecond value is just rounded to the nearest millisecond. (Matthias)
why? that is because of context switching (part of the OS CPU scheduling)
How? calling Thread.sleep(t) makes the current thread to be moved from the running queue to the waiting queue. After the time 't' reached the the current thread get moved from the waiting queue to the ready queue and then it takes some time to be picked by the CPU and be running.
Solution: call Thread.sleep(t*10); instead of calling Thread.Sleep(t) inside loop of 10 iterations ...
I have face this problem before when waiting for asynchronous process to return a result.
Thread.sleep is a problem on multi thread scenario. It tends to oversleep. This is because internally it rearrange its priority and yields to other long running processes (thread).
A new approach is using ScheduledExecutorService interface or the ScheduledThreadPoolExecutor introduce in java 5.
Reference: http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ScheduledExecutorService.html
It might NOT be a problem, it depends.
In my case, I use Thread.sleep() to wait for a couple of seconds before another reconnect attempt to an external process. I have a while loop for this reconnect logic till it reaches the max # of attemps. So in my case, Thread.sleep() is purely for timing purpose and not coordinating among multithreads, it's perfectly fine.
You can configure you IDE in how this warning should be handled.
I suggest looking into the CountDownLatch class. There are quite a few trivial examples out there online. Back when I just started multithreaded programming they were just the ticket for replacing a "sleeping while loop".
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.