Can I get a complete simple scenario i.e. tutorial that suggest how this should be used, specifically with a Queue?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
The
wait()
andnotify()
methods are designed to provide a mechanism to allow a thread to block until a specific condition is met. For this I assume you're wanting to write a blocking queue implementation, where you have some fixed size backing-store of elements.The first thing you have to do is to identify the conditions that you want the methods to wait for. In this case, you will want the
put()
method to block until there is free space in the store, and you will want thetake()
method to block until there is some element to return.There are a few things to note about the way in which you must use the wait and notify mechanisms.
Firstly, you need to ensure that any calls to
wait()
ornotify()
are within a synchronized region of code (with thewait()
andnotify()
calls being synchronized on the same object). The reason for this (other than the standard thread safety concerns) is due to something known as a missed signal.An example of this, is that a thread may call
put()
when the queue happens to be full, it then checks the condition, sees that the queue is full, however before it can block another thread is scheduled. This second thread thentake()
's an element from the queue, and notifies the waiting threads that the queue is no longer full. Because the first thread has already checked the condition however, it will simply callwait()
after being re-scheduled, even though it could make progress.By synchronizing on a shared object, you can ensure that this problem does not occur, as the second thread's
take()
call will not be able to make progress until the first thread has actually blocked.Secondly, you need to put the condition you are checking in a while loop, rather than an if statement, due to a problem known as spurious wake-ups. This is where a waiting thread can sometimes be re-activated without
notify()
being called. Putting this check in a while loop will ensure that if a spurious wake-up occurs, the condition will be re-checked, and the thread will callwait()
again.As some of the other answers have mentioned, Java 1.5 introduced a new concurrency library (in the
java.util.concurrent
package) which was designed to provide a higher level abstraction over the wait/notify mechanism. Using these new features, you could rewrite the original example like so:Of course if you actually need a blocking queue, then you should use an implementation of the BlockingQueue interface.
Also, for stuff like this I'd highly recommend Java Concurrency in Practice, as it covers everything you could want to know about concurrency related problems and solutions.
Example for wait() and notifyall() in Threading.
A synchronized static array list is used as resource and wait() method is called if the array list is empty. notify() method is invoked once a element is added for the array list.
Not a queue example, but extremely simple :)
Some important points:
1) NEVER do
Always use while(condition), because
while(!pizzaExists){ wait(); }
.2) You must hold the lock (synchronized) before invoking wait/nofity. Threads also have to acquire lock before waking.
3) Try to avoid acquiring any lock within your synchronized block and strive to not invoke alien methods (methods you don't know for sure what they are doing). If you have to, make sure to take measures to avoid deadlocks.
4) Be careful with notify(). Stick with notifyAll() until you know what you are doing.
5)Last, but not least, read Java Concurrency in Practice!
Have you taken a look at this Java Tutorial?
Further, I'd advise you to stay the heck away from playing with this kind of stuff in real software. It's good to play with it so you know what it is, but concurrency has pitfalls all over the place. It's better to use higher level abstractions and synchronized collections or JMS queues if you are building software for other people.
That is at least what I do. I'm not a concurrency expert so I stay away from handling threads by hand wherever possible.
Even though you asked for
wait()
andnotify()
specifically, I feel that this quote is still important enough:Josh Bloch, Effective Java 2nd Edition, Item 69: Prefer concurrency utilities to
wait
andnotify
(emphasis his):Example