Referring to this topic(How to pause Thread execution), Peter Knego said:
Loop must be inside synchronized block.
But I don't see the point of synchronization if only one instance is there.
In another case, if the thread class has multiple instances and they are copping with different variables, does the loop need to be synchronized.
Actually, I wrote a few programs using threads (with multiple instances) without considering synchronization and they works fine.
You must synchronize any access to shared state. If all of your instances access local storage, then they are thread safe. If your methods are thread safe, they do not require synchronization. If you had a static (e.g. global) resource, and modified it in multiple threads then that is likely to be non-thread safe (excluding atomic operations of course).
The answer says
Use synchronized, wait() and notify() for that.
Create an atomic flag (e.g. boolean field) in the thread to be stopped. Stoppable thread monitors this flag in the loop. Loop must be inside synchronized block.
When you need to stop the thread (button click) you set this flag.
Thread sees the flag is set and calls wait() on a common object (possibly itself).
When you want to restart the thread, reset the flag and call commonObject.notify().
You cannot call wait() or notify on an object unless you get a lock on it's monitor. And putting it inside synchronized block is a way to do that.
this is because the wait and notify are part of the condition variable and using them without synchronizing on them leads in the general use-case to race conditions
the normal way of using wait is
synchronized(this){
while(someCondition())
wait();//while loop is needed to combat spurious wakeups
}
and you wake it up with
synchronized(this){
adjustCondition();
notify();
}
if you didn't synchronize on the condition as well then you get into a race for example
you just tested someCondition() and got true so you need to wait. but before you get a chance to another thread executes the adjustCondition();notify(); block
but the first thread will still enter the wait() (because the condition has already been checked) and which may lead to deadlock
The Thread monitor needs to be synchronized in your case. This is done only for the actual wait call, because it requires that. I recommend to have a special wait Object for this to not accidental synchronize on something else.
final static Object threadPauseMonitor = new Object();
// ...
while (shouldPause.get()) {
synchronized(threadPauseMonitor) {
threadPauseMonitor.wait();
}
}
Where shouldPause is an AtomicBoolean. Please note the while to counter the malicious spurious wakeup that can possibly occur.
Related
Someone at work just asked for the reasoning behind having to wrap a wait inside a synchronized.
Honestly I can't see the reasoning. I understand what the javadocs say--that the thread needs to be the owner of the object's monitor, but why? What problems does it prevent? (And if it's actually necessary, why can't the wait method get the monitor itself?)
I'm looking for a fairly in-depth why or maybe a reference to an article. I couldn't find one in a quick google.
Oh, also, how does thread.sleep compare?
edit: Great set of answers--I really wish I could select more than one because they all helped me understand what was going on.
Lots of good answers here already. But just want to mention here that the other MUST DO when using wait() is to do it in a loop dependent on the condition you are waiting for in case you are seeing spurious wakeups, which in my experience do happen.
To wait for some other thread to change a condition to true and notify:
synchronized(o) {
while(! checkCondition()) {
o.wait();
}
}
Of course, these days, I'd recommend just using the new Condition object as it is clearer and has more features (like allowing multiple conditions per lock, being able to check wait queue length, more flexible schedule/interrupt, etc).
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
lock.lock();
try {
while (! checkCondition()) {
condition.await();
}
} finally {
lock.unlock();
}
}
If the object does not own the object monitor when it calls Object.wait(), it will not be able to access the object to setup a notify listener until the the monitor is released. Instead, it will be treated as a thread attempting to access a method on a synchronized object.
Or to put it another way, there is no difference between:
public void doStuffOnThisObject()
and the following method:
public void wait()
Both methods will be blocked until the object monitor is released. This is a feature in Java to prevent the state of an object from being updated by more than one thread. It simply has unintended consequences on the wait() method.
Presumably, the wait() method is not synchronized because that could create situations where the Thread has multiple locks on the object. (See Java Language Specifications/Locking for more info on this.) Multiple locks are a problem because the wait() method will only undo one lock. If the method were synchronized, it would guarantee that only the method's lock would be undone while still leaving a potential outer lock undone. This would create a deadlock condition in the code.
To answer your question on Thread.sleep(), Thread.sleep() does not guarantee that whatever condition you are waiting on has been met. Using Object.wait() and Object.notify() allows a programmer to manually implement blocking. The threads will unblock once a notify is sent that a condition has been met. e.g. A read from disk has finished and data can be processed by the thread. Thread.sleep() would require the programmer to poll if the condition has been met, then fall back to sleep if it has not.
It needs to own the monitor, since the purpose of the wait() is to release the monitor and let other threads obtain the monitor to do processing of their own. The purpose of these methods (wait/notify) is to coordinate access to synchronized code blocks between two threads that require each other to perform some functionality. It is not simply a matter of making sure access to a data structure is threadsafe, but to coordinate events between multiple threads.
A classic example would be a producer/consumer case where one thread pushes data to a queue, and another thread consumes the data. The consuming thread would always require the monitor to access the queue, but would release the monitor once the queue is empty. The producer thread would then only get access to write to the thread when the consumer is no longer processing. It would notify the consumer thread once it has pushed more data into the queue, so it can regain the monitor and access the queue again.
Wait gives up the monitor, so you must have it to give it up. Notify must have the monitor as well.
The main reason why you want to do this is to ensure that you have the monitor when you come back from wait() -- typically, you are using the wait/notify protocol to protect some shared resource and you want it to be safe to touch it when wait returns. The same with notify -- usually you are changing something and then calling notify() -- you want to have the monitor, make changes, and call notify().
If you made a function like this:
public void synchWait() {
syncronized { wait(); }
}
You would not have the monitor when wait returned -- you could get it, but you might not get it next.
Here's my understanding on why the restriction is actually a requirement. I'm basing this on a C++ monitor implementation I made a while back by combining a mutex and a condition variable.
In a mutex+condition_variable=monitor system, the wait call sets the condition variable into a wait state and releases the mutex. The condition variable is shared state, so it needs to be locked to avoid race conditions between threads that want to wait and threads that want to notify. Instead of introducing yet another mutex to lock its state, the existing mutex is used. In Java, the mutex is correctly locked when the about-to-wait thread owns the monitor.
Mostly wait is done if there is a condition say a queue is empty.
If(queue is empty)
queue.wait();
Let us assume the queue is empty.
In case if the current thread pre-empts after checking the queue, then if another
thread adds few elements to queue, the current thread will not know and will go for wait
state. Thats wrong.
So we should have something like
Synchornized(queue)
{
if(queue is empty)
queue.wait();
}
Now let us consider what if they made wait itself as synchronized. As already mentioned in one of the comments, it releases only one lock. That means if wait() was synchronized in the above code only one lock would have been released. Implies that current thread will go for wait with the lock for the queue.
I have a small question that makes me a little confused.
This is my code:
public synchronized void P() {
while(!_state) {
this.wait();
}
_state = false;
}
This method is responsible for taking semaphore.
Why it is not possible to build binary semaphore with if statement instead of while loop?
The oracle docs says:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is
done with the object.
So exactly only one thread should be inside the P() method -> so only one thread should be blocked on wait() method. Rest of threads should be blocked on P() method level. But when I am replacing while() for if() it does not work properly
Why it is not possible to build binary semaphore with if statement instead of while loop?
For a deep answer, you should work through Oracle's Guarded Blocks tutorial.
The shorter answer is, there's a couple of reasons why _state could be false when the wait() call returns:
Multiple consumers: It generally is safer to wake sleepers with notifyAll() instead of notify(), and if you write a program in which two or more threads could call the P() function, you probably only want one of them to be allowed to proceed when some other thread calls the V() function. So, if they all "wake up", you'll want just one to set _state=false; and you'll want the others to go back to sleep.
The same object is getting notifyAll() calls for more than one reason. It's not good practice, but it happens, especially in projects where many developers contribute to the code. In that case, you don't wan the P() call to return if the object was notified for the wrong reason. You want it to go back and continue waiting.
The documentation for o.wait() says that it is allowed to return even when object o has not been notified at all. This is known as "spurious wakeup." It happens rarely, and only in some operating systems, but they allow it because it enables a more efficient implementation of wait() and notify().
synchronized method is equivalent to synchronized(this) block.
Only 1 thread is allowed to enter synchronized block. By entering it, thread aquires lock. When you wait inside sync block, you release the lock (object monitor) and park current thread. At this moment, another thread is allowed to enter that block. Execution will continue when other thread will invoke notify or notifyAll on the same object that wait was invoked. Notified thread will "exit wait state" when given sync block's lock will be released.
To sum up - wait does not work like you expect, it does not block execution, only puts waiting thread to sleep, allowing other threads to aquire sync lock.
So you cannot do what you want to achieve, because wait works differently then you expect. What you want to use here, is ReentrantLock. https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html
When we are using wait and notify in thread environment. I have a class to process data as background process. And when there is no data to process it should call wait.
synchronized(some_object){
wait();
}
In another class I am adding the data again. I need call notify() method.
synchronized(some_object){
runnabale_object.notify();
}
Why i should use same object for synchronized block in those two different class. As i read synchronize is used to
The "Synchronized" keywords prevents concurrent access to a block of
code or object by multiple Threads.
But these two are different block. But i can understand the problem when we use multiple threads. While one thread block other can call notify before the same thread call notify.
My Questions
Can we use different lock objects (synchronized(object)) for single threaded environment?
Best way of use same lock object when we have wait and notify in different classes?
Can we use different lock objects (synchronized(object)) for single threaded environment?
In a single threaded environment, you don't need the locks. You can use anything you want or nothing at all.
In a single threaded environment you can guarantee no thread is wait()ing so the notify() will not do anything.
Best way of use same lock object when we have wait and notify in different classes?
When you notify(), you must perform a state change. When you wait() in a loop you much check for that state change. If you don't do this you can have two problem.
the notify() is lost
the wait() wakes spuriously, ie no notify.
when there is no data to process it should call wait.
Not when, but while.
Wait and notify are low-level primitive operations that are meant to be used in a very specific way.
In a consumer thread:
synchronized(lock) {
while (thereIsNothingToProcess()) {
lock.wait();
}
processSomething();
}
In a producer thread:
synchronized(lock) {
makeSomethingAvailableToProcess();
lock.notifyAll(); //or lock.notify() if you think you can get away with it.
}
If you follow this exact pattern, then:
You will not run into trouble when multiple consumers are competing for the same thing-to-be-processed,
You will not run into trouble because of spurious wakeups, and
You will not run into trouble because of the lost notification problem.
I've had the same question so I looked it up. The reason that two synchronized block can be used in the same object, is that 'wait()' will actually release the monitor so that other thread can obtain the guardian of the same object.
I have following piece of code:
synchronized void myMethod() {
String s="aaa";
try {
s.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
The code throws exception ...
I have seen codes using wait method on threads which is self explainable and logical..
why would one use wait method on an object like string instead of using it on main thread?
what is its use?
are there any practical implementations like this?
Thanks in advance
Your sample code won't work because the method is synchronizing on the instance that myMethod is called on, while the wait is called on the string. It will cause an IllegalMonitorStateException. You have to call wait and notify on the same object that you're locking on. The threads that get notified are the ones waiting on the lock that notify is called on.
Locking on a string object is a bad idea, don't do it. You don't want to lock on things where you can't reason about who can acquire them because anybody could acquire them. Some other code elsewhere in the application could be locking on the same string value, and you'd have the potential for strange interactions, deadlocking because the other code was taking your lock, or have the other code notifying you. Do you want to have to think about how strings are pooled when debugging some multithreading behavior?
You can limit who can acquire your lock by defining your own lock and making it private, like this:
private final Object LOCK = new Object();
so only threads calling the methods of the object you're controlling access to can acquire the lock:
public void myMethod() {
synchronized(LOCK) {
...
}
}
That way you know exactly what can acquire the lock, it's not available to every thread in the application. The lock can be acquired by anything that can get a reference to that object, so keep the reference private.
The way your example uses wait without a loop with a condition variable is very suspect. A thread can exit from a call to wait without having been notified. Even if a thread is notified, that doesn't give it any special priority with the scheduler. Another thread can barge in and do something, possibly something affecting the state that the notification was alerting the waiting thread to, between the time the thread is notified and the time that the thread can reacquire the lock it gave up when it started waiting. For both reasons there needs to be a loop where the thread retests a condition when it wakes from waiting.
Also if by "codes using wait method on threads" you mean code where a Thread object is used as a lock, that's another thing to avoid doing, see the API documentation for Thread#join:
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
You first need to be synchronized on the Object before calling wait. This is where you are getting the exception from.
void test() {
String s = "AAA";
synchronized( s ) {
s.wait();
}
}
The same thing must be done when you call notify, but in this case it is a very very bad idea because if a thread enters this method it will never return. Although considering it is a String literal you may be able to get away with it by using the same literal in another method in the same class, but don't count on it.
wait() method is implemented in Object, and String extends object so it can be used.
why someone use it? ask him. its not a programming question.
something i can think of:
he could be using "lock1".wait() in one class and "lock1".notify() in other, it will be something like global lock object
because literals are interned by
the compiler and thus refer to the same object
but its VERY VERY BAD PRACTICE
This is an example of synchronization with no affect.
First of all, it is unlikely you will need to synchronize on String, it is immutable after all, therefore, you don't need it to perform anything asynchronously.
Second, you are likely to be synchronizing on the incorrect object anyways, no correctly written program would use String as a synchronization lock.
Third and finally, s is a local variable. In fact, it holds exactly the same pattern that JCIP specifically tells you not to use if you inline it:
synchronized (new Object()) {
// ...
}
This is synchronization without effect, as it does not guarantee the purpose of the synchronized keyword: serialized access, lock and release semantics that require that only one thread execute the synchronized block at any given time.
Because of this, each thread will have their own lock - not good.
I know, that we use this idiom for waiting for notification to handle spurious wakeups:
synchronized (obj) {
while(somecond)
obj.wait();
}
If a spurious wake up arises, we'll just check the state and return back to waiting.
But, consider the situation:
We begin waiting, and obj.wait() releases lock on obj.
Waiting thread is spuriously notified by OS
We return to checking condition (with obj lock released due to wait)
obj.notify() is called right in that moment.
Yes, condition checking is extremely fast and chances, that we can be in condition checking and not in obj.wait(), are negligibly small. In that case we can loose obj.notify() call.
Am I misunderstanding something, or we really can loose notification using this pattern?
Another thread needs the lock on obj to be able to call obj.notify(). And it can't have it if your thread is in the while loop not waiting, since your thread also needs the lock on obj to be in the while loop.
The call to obj.wait() will not return until an obj.notify() has been called. However, you might fail to respond to an obj.notify() if another thread is also waiting and the system decides to notify that thread instead. If you want to avoid that, you can use obj.notifyAll(). If only one thread is waiting, you cannot lose the notification with this pattern.
Note that the other thread cannot call obj.notify() unless it holds the lock. If this thread is busy checking the condition, then it has the lock and the other thread cannot issue a notification. The synchronized block is essential to the operation.
In the case you present, Thread A is evaluating the condition, and Thread B is calling notify such that Thread A misses the notify call
This scenario would not be possible for that notify to be called since it must own the lock that Thread A is using in the synchronized block - only one thread can own that lock at once. See the javadoc on notify for more details.
The modifications to the state we are checking should be made, while the lock on obj is held by whomever calls obj.notify() afterwards. So, assuming we are currently checking the state, we are also holding the lock on obj.
If we are getting a spurious wake up, and the state has not changed, no one should have called obj.notify(). If the state has changed and we we miss a obj.notify(), it does not matter: For all intends, a spurious wake up and a wakeup by a call to obj.notifiy() have the same effect now.
The lesson is, that the state we are checking for should only be changed, while whoever is changing the state holds a lock on the object we are waiting on.
Since most of the answers insist on the impossibility of the scenario it’s worth to adjust that:
It is always possible to have a call to notify without a matching waiting thread. This might happen when the notifying thread invokes notify before the other thread even entered the entire synchronized block. The notify method might even have been called multiple times before any thread enters a synchronized block to wait and the wait-notify mechanism won’t count these.
So you have to handle the case that you missed a notify, e.g. by checking the condition within the synchronized block before calling wait. But by doing so you add the possibility to process and reset the condition while the matching notify is indeed pending.
Therefore you must be always aware of the possibilities that either
you may have missed one or more notify invocations
you may receive an obsolete notify
That’s why the correct handling loop likes like that
synchronized(obj) {
while(somecond)
obj.wait();
}
From an application’s point of view there is no difference between outdated pending notifys and the spurious wakeups generated by the JVM/OS without associated notify invocations. That’s why there is no attempt to prevent spurious wakeups by the JVM. The effort would be wasted as the logic wouldn’t change.