I need to wake up or send to sleep a single Thread sometimes, and I'm wondering what is the best and most efficient way to do it.
The first solution is signaling combined with wait-notify (I know how to implement this pattern properly, that's not the question).
I read it somewhere that using the java.concurrent library and CountDownLatch for signaling is more efficient. I checked concurrent.locks.Condition as well, but this topic states that it's merely a (programmer-wise) more safe and generalized construct, without a performance benefit compared to notify/notifyAll. Peter Lawrey recommends using the Concurrency library instead of notify-notifyAll in this comment, so now I'm confused what is the best practice to use.
A related question: which is better performance-wise, notify or notifyAll in my case (i.e. if I have one thread)? I know there are lot of similar threads about this, but none of them give a clear answer. In my case, functionally, it doesn't matter which I use, but I wonder which is faster, then.
IMO they don't make much difference "performance-wise" since they all suspend the thread calling the corresponding wait so most likely the underlying mechanisms are very similar. And why would performance matter so much anyway? Unless you have some extremely fast wait/signal pattern in which the signal comes immediately after the wait, making a context-switch too expensive and requiring perhaps a spinlock instead, there's no need to worry about performance.
You should implement what you think is the most convenient method programming-wise and then benchmark and see if you really need something more performant.
wait-notify is perfectly fine.
since there's only one thread on the waiting list, there's no difference, semantics or performance wise, between notify and notifyAll.
Related
IntelliJ suggests that I replace the deprecated Thread.suspend() with Thread.checkAccess(). Based on the (very brief) documents, checkAccess() seems like a good idea, but also seems quite different than .suspend(), which certainly seems very bad based on the docs. Yet those same docs don't seem to offer a useful alternative to .suspend(), except to suggest that each solution presented has some non-trivial drawbacks.
At the same time, while much better, it seems .checkAccess() relies on there being a SecurityManager implemented, so simply clicking "fix this" also seems like a bad idea without some well-thought-out implementation.
I have made the suggested change, and nothing has broken – yet... But I wonder...
If .checkAccess() is the best alternative, what is the best way to implement it in a nutshell? If it isn't, what is a better alternative?
According to the docs of Thread.suspend:
First, the checkAccess method of this thread is called with no arguments. This may result in throwing a SecurityException (in the current thread).
If the thread is alive, it is suspended and makes no further progress unless and until it is resumed.
So, invoking checkAccess() is preserving the "safe" part of the suspend() call, in that it will throw an exception if you don't have access, but it won't then proceed to the dangerous deadlocking operation.
I don't precisely know what "suspend" does - I have never used this method, and it is helpfully defined as "Suspends this thread". But if you simply want to wait for something to happen, you could wait on some object:
synchronized (thing) {
thing.wait();
}
then call thing.notify() from the thread you would otherwise be using to resume the thread.
But note that the primitive synchronization methods on Object are inherently difficult to use - for example, Object.wait() may spuriously wake up. You should rarely be using them directly (or Thread, for that matter).
There is a bunch of higher-level synchronization objects in the java.util.concurrent package. For example, you could have a queue shared between your "suspended" and "resuming" threads, where, at the point you want to suspend, one thread waits for the other to put something into the queue.
I have read this answer:
Difference between wait-notify and CountDownLatch
I know both process are different,
CountDownlatch is a new mechanism while wait/notify is a pristine
way of co coordinating between threads
wait is a method of Object, await is a method of CountDownlatch.
using CountDownlatch is easier and cleaner etc etc.
My question is more of the functional aspect:
Is there any situation which cannot be solved by wait/notify mechanism but can be solved only by CountDownLatch?
If no,then functionally, CountDownlatch was introduced solely to make coordination between threads easier and cleaner, right?
Sure you can create the same functionality just with wait, notify, synchronized and so on. CountDownLatch is a normal Java class implemented using such primitives. For details you can have a look at the actual source code: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/CountDownLatch.java
The classes in java.util.concurrent are designed to make certain multithreading scenarios more easier to code and manage. You can use low-level constructs such as wait and notify but you really need to know what you are doing.
Here is the excerpt from the API:
Utility classes commonly useful in concurrent programming. This
package includes a few small standardized extensible frameworks, as
well as some classes that provide useful functionality and are
otherwise tedious or difficult to implement.
Consider a case where you may not want to wait if a condition is met. You could get your hands dirty and probe a lock, but this is often buggy.
A CountDownLatch comes to the rescue, yes for convenience, but not solely to solve the wait/notify paradigm.
The obvious use of CountDownLatch as a way to wait for multiple conditions also comes to mind.
Why reinvent the wheel when it's available first party?
while(!anotherThread.isDone());
or
while(!anotherThread.isDone())
Thread.sleep(5);
If you really need to wait for a thread to complete, use
anotherThread.join()
(You may want to consider specifying a timeout in the join call.)
You definitely shouldn't tight-loop like your first snippet does... and sleeping for 5ms is barely better.
If you can't use join (e.g. you're waiting for a task to complete rather than a whole thread) you should look at the java.util.concurrent package - chances are there's something which will meet your needs.
IMHO, avoid using such logic altogether. Instead, perhaps implement some sort of notification system using property change listeners.
As others have said, it's better to just use join in this case. However, I'd like to generalize your question and ask the following:
In general when a thread is waiting for an event that depends on another thread to occur is it better to:
Use a blocking mechanism (i.e. join, conditional variable, etc.) or
Busy spin without sleep or
Busy spin with sleep?
Now let's see what are the implications for each case:
In this case, using a blocking call will effectively take your thread off the CPU and not schedule it again until the expected event occurs. Good for resource utilization (the thread would waste CPU cycles otherwise), but not very efficient if the event may occur very frequently and at small intervals (i.e. a context switch is much more time-consuming than the time it takes for the event to occur). Generally good when the event will occur eventually, but you don't know how soon.
In case two, you are busy spinning, meaning that you are actively using the CPU without performing useful work. This is the opposite of case 1: it is useful when the event is expected to occur very very soon, but otherwise may occupy the CPU unnecessarily.
This case is a sort of trade-off. You are busy spinning, but at the same time allowing other threads to run by giving up the CPU. This is generally employed when you don't want to saturate the CPU, but the event is expected to occur soon and you want to be sure that you will still be there in almost real time to catch it when it occurs.
I would recommend utilizing the wait/notify mechanism that is built into all Java objects (or using the new Lock code in Java 5).
Thread 1 (waiting for Thread2)
while(!thread2.isDone()) {
synchronize(thread2.lockObject) {
thread2.lockObject.wait();
}
}
Thread 2
// finish work, set isDone=true, notify T1
thread2.lockObject.notify();
'lockObject' is just a plain (Object lockObject = new Object()) -- all Java objects support the wait/notify calls.
After that last call to notify(), Thread1 will wake up, hit the top of the while, see that T2 is now done, and continue execution.
You should account for interrupt exceptions and the like, but using wait/notify is hugely helpful for scenarios like this.
If you use your existing code, with or without sleep, you are burning a huge number of cycles doing nothing... and that's never good.
ADDENDUM
I see a lot of comments saying to use join - if the executing thread you are waiting on will complete, then yes, use join. If you have two parallel threads that run at all times (e.g. a producer thread and a consumer) and they don't "complete", they just run in lock-step with each other, then you can use the wait/notify paradigm I provided above.
The second one.
Better though is to use the join() method of a thread to block the current thread until it is complete :).
EDIT:
I just realised that this only addresses the question as it applies to the two examples you gave, not the question in general (how to wait for a boolean value to be changed by another Thread, not necessarily for the other Thread to actually finish).
To answer the question in general I would suggest that rather than using the methods you described, to do something like this I would recommend using the guarding block pattern as described here. This way, the waiting thread doesn't have to keep checking the condition itself and can just wait to be notified of the change. Hope this helps!
Have you considered: anotherThread.join() ? That will cause the current one to be 'parked' without any overhead until the other one terminates.
The second is better than the first, but neither is very good. You should use anotherThread.join() (or anotherThread.join(timeout)).
Neither, use join() instead:
anotherThread.join();
// anotherThread has finished executing.
I saw the below statement in Java Specifications.
Programs where threads hold (directly
or indirectly) locks on multiple
objects should use conventional
techniques for deadlock avoidance,
creating higher-level locking
primitives that don't deadlock, if
necessary.
So, What are the "Conventional Techniques" to follow to avoid deadlock? I'm not pretty clear with this (not understood properly, explanation needed).
The most common technique is to acquire resources (locks) in some consistent well-defined order.
The following article by Brian Goetz might be helpful: http://www.javaworld.com/javaworld/jw-10-2001/jw-1012-deadlock.html
It's pretty old, but explains the issues well.
As a somewhat absract suggestion, an answer to this might be "Have a plan for handling locks and stick to it".
The danger of locking is where, in short, one thread holds lock A and is trying to get lock B, while another thread holds lock B and is trying to get lock A. As noted by another answer, the clasic way to avoid this is to get locks in a consistent order. However, a good discipline is to minimize the amount of work that your code does with a lock held. Any code that calls another function with a lock held is a potential problem: what if that other function tries to get another lock? What if someone else later modifies that function to get a lock? Try to form a clear pattern of what functions can be called with locks held, and what cannot, and make sure the comments in your code make this all clear.
Don't do locking! Seriously. We get immense performance (100k's of transactions at sub-millisecond latency) at my work by keeping all our business logic single threaded.
Guys, can anyone give a simple practical example of LockSupport & AbstractQueuedSynchronizer use? Example given in javadocs is quite strained.
Usage of Semaphore permits is understood by me.
Thanks for any response.
If youre talking about using a locking mechanism (or even sync barriers) just use a java.util.concurrent.Lock. The obvious suggestion is to user a ReentrantLock which delegates to a Synch. The synch is an AQS which in turn uses LockSupport.
Its all done under the covers for you.
Edit:
No let's go over the practical uses of AbstractQueuedSynchronizer (AQS).
Concurrency constructs though can be very different in their usage all can have the same underlying functions.
I.e. Under some condition park this thread. Under some other condition wake a thread up.
This is a very broad set of instructions but makes it obvious that most concurrency structures would need some common functionality that would be able to handle those operations for them. Enter AQS. There are five major synchronization barriers.
ReentrantLock
ReadLock
WriteLock
Semaphore
CountDownLatch
Now, all these five structures have very different set of rules when using them. A CountdownLatch can allow many threads to run at the same time but forces one (or more) threads to wait until at least n number of threads count down on said latch.
ReentrantLock forces only one thread at a time to enter a critical section and queues up all other threads to wait for it to completed.
ReadLock allows any number of reading threads into the critical section until a write lock is acquiered.
The examples can go on, but the big picture here is they all use AQS. This is because they are able to use the primitive functions that AQS offers and implements more complex functionality on top of it. AQS allows you to park unpark and wake up threads ( interruptibly if need be) but in such a way that you can support many complex functions.
they are not meant for direct use in client code; more for helping building new concurrent classes.
AQS is a wonderful class for building concurrency primitives – but it is complex and requires a bit of study to use it properly. I have used it for a few things like lazy initialisation and a simple fast reusable latch.
As complex as it is, I don't think AQS is particularly vague, it has excellent javadocs describing how to use it properly.
2.7 release of Disruptor uses LockSupport.parkNanos instead of Thread.sleep to reduce latency:
http://code.google.com/p/disruptor/
AFAIK, AbstractQueuedSynchronizer is used to manage state transitions. The JDK uses it to extend Sync, an internal class for java.util.concurrent.FutureTask. The Sync class manages the states (READY, RUNNING, RAN, and CANCELLED) of FutureTask and the transitions between them.
This allows, as you may know, FutureTask to block on FutureTask.get() until the RAN state is reached, for example.