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.
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 am learning about cooperation between concurrent tasks and I have got that question and a possible answer to it. I would like to make sure I understand it correctly.
So to call a.wait() it is first required to synchronize on the object a or to be more precise a thread must become the owner of the a's monitor. As far as I understand, the only reason why a.wait() should be called in a synchronized context (together with a.notify()/a.notifyAll()) is to avoid a race condition/The Lost Wake-Up Problem. But theoretically, it is possible to avoid the race condition calling a.wait(),a.notify()/a.notifyAll() by synchronizing on some other object, like this:
Thread #1:
synchronized(b) {
…
a.wait(); // here a thread owns only one monitor: the monitor of the object stored in the variable b, where a != b
…
}
Thread #2:
synchronized(b) {
…
a.notify(); // the same here
…
}
The expected behavior is: the thread #1 acquires the monitor of b, enters the critical section, invokes a.wait(), then waits on a and releases the monitor of b. Afterwards the thread #2 acquires the monitor of b, enters the critical section, invokes a.notify() (the thread #1 gets notified), exits the critical section and releases the monitor of b, then the thread #1 acquires the monitor of b again and continues running. Thus, only one critical section synchronized on b can run at a time and no race condition can occur. You may ask, “but how would wait() know that the object b is used in this case to avoid the race condition and thus its monitor must be released?”. Well, that way it wouldn’t know. But maybe the wait method could take an object as an argument to know which object’s monitor to release, for example, a.wait(b), to wait on a and release the monitor of b. But there is no such an option: a.wait() causes a thread to wait on a and releases the monitor of exactly the same a. Period. The invocation of the wait and notify methods in the code above results in IllegalMonitorStateException.
According to this information from the Wikipedia article, the functionality of the wait, notify/notifyAll methods is built into every object's monitor where it is integrated into the functionality of the synchronization mechanism at the level of every individual object. But still it doesn't explain why it was done this way in the first place.
My answer to the question: before calling the wait method of an object, a thread should own the monitor of exactly the same object because to avoid a race condition this object is always not only a viable option but the best one.
Let’s see if there are any situations where it could be undesirable to synchronize on an object before invoking its wait, notify/notifyAll methods (plus some relevant logic). Synchronizing on the object would block it for other threads which could be undesirable if the object has some other synchronized methods (and/or there are some critical sections synchronized on the object) having nothing to do with the waiting logic. In that case it is always possible to refactor the corresponding class(es) so that the wait and notify/notifyAll methods operate on one object, while other synchronized methods/blocks operate on another one(s). For example, one of possible solutions could be creating a dedicated object specifically for a waiting logic (to wait and synchronize on) like in the example below:
public class A {
private Object lock = new Object(); // an object to synchronize and wait on for some waiting logic
private boolean isReady = false;
public void mOne() throws InterruptedException {
synchronized(lock) { // it blocks the instance of the Object class stored in the variable named lock
while(!isReady) {
lock.wait();
}
}
}
public void mTwo() {
synchronized(lock) { // the same here
isReady = true;
lock.notify();
}
}
synchronized public void mThree() { // it blocks an instance of A
// here is some logic having nothing to do with the above waiting and
// mThree() can run concurrently with mOne() and mTwo()
}
}
So there is no need to synchronize on some voluntary object to avoid a certain race condition regarding calling wait, notify/notifyAll methods. If it was allowed it would only cause unnecessary confusion.
Is it correct? Or maybe I am missing something here. I would like to make sure I don't miss anything important.
Oracle documentation: wait, notify, notifyAll
In Java using the synchronized keyword all within a single object and thread.
Can I call a synchronized method that calls a non-synchronized method that calls a synchronized method, without the final synchronized method blocking for the first synchronized method to be completed?
With a single object and a single thread, there's no problem.
Your only thread is able to acquire all the locks, and due to re-entrancy, it can acquire them several times.
Even if we add another thread, it'll work (with one object). One thread will acquire the first lock, blocking the second thread, and execution continues normally.
With multiple threads and multiple objects, the answer is "it depends on how the code is written".
Your code can always call a method whether it is synchronized or not. A better question is, what will happen when your code calls it.
A synchronized method that looks like this:
synchronized void foobar() {
doSomething();
}
Actually is just a short-hand way of writing this:
void foobar() {
synchronized(this) {
doSomething();
}
}
So any question about calling a synchronized method really is a question about executing a synchronized block. There are three things that could happen when your code enters synchronized(this) {...}.
1) If the this object is not locked, then it will be locked in the name of the calling thread, the thread will execute the statements in the block, and then it will unlock the lock when it's done.
2) If the this object already has been locked by the calling thread, then the thread will simply execute the statements in the block.
3) If the this object is locked by some other thread, then the calling thread will wait until the other thread unlocks it, and then it will proceed as in case (1).
The only way you can get into trouble is if your code attempts to lock two different locks. Then, if your design is not well thought out, two or more threads could deadlock, which is something you can read about elsewhere.
If a class has both synchronized and non-synchronized methods, multiple
threads can still access the class's non-synchronized methods.If you have
methods that don't access the data you're trying to protect, then you don't
need to synchronize them. Synchronization can cause a hit in some cases (or
even deadlock if used incorrectly)
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.
i know that wait() method always written in synchronized method/block and make lock on Object but i want to only know that what problem is arise at that time when this all methods are in Thread class ?
They are also in the Thread class. But a thread instance here is equally well suited as a synchronization object as any other object.
In addition, there have already been voices that question this decision of sun, since now every object carries the burden to be able to be synchronized on, and IMHO they should have refactored this out to separate objects long ago.
If I need to have something to synchronize on, I often do:
private Object syncObject = new Object();
Then I can do my
synchronized(syncObject)
everywhere in the code and do not have to bother with anyone else accidentially synchronizing on this.
The problem with using them on a Thread object is that the Thread uses this lock for it own purposes. This is likely to lead to confusion and odd bugs.
These method's context is a lock associated with every object in Java so we can't move them to the Thread class. For example we might do something like this. Thread 1 adds an item to a list and notifies other threads about it. Thread 2 waits for a list update and does something with it:
thread 1
synchronized (lock) {
list.add(item);
lock.notifyAll();
}
thred 2
synchronized (lock) {
list.wait();
... do something with list
}
If these methods were moved to a thread, the thing we done here would be impossible.
These methods works on the locks and locks are associated with Object and not Threads. Hence, it is in Object class.
The methods wait(), notify() and notifyAll() are not only just methods, these are synchronization utility and used in communication mechanism among threads in Java.
For more explanation read: Why wait() ,notify() and notifyAll() methods are in Object class instead of Thread class?