i**p 发帖数: 902 | 1 I have the same question as this.
--------------------------------------------
I am confused a bit about wait and notify/notifyall.
I know there is a lock for every java object. I know wait will release the
lock for other thread. How about notify/notifyall? Does notify/notifyall
realse the lock it is holding for other thread?
-------------------------------------------------
There are 2 different answers for it on this link
http://stackoverflow.com/questions/5999193/java-wait-notify-not
Could anyone here tell me which one is the right answer?
The result from my test seems that the thread calling "notify" releases the
lock right away. If this is true, the rest of code in the synchronized
method is not under protection by the lock. |
s*******e 发帖数: 3042 | 2 They only wake up blocked thread, the monitor is not released by the thread
until the end of the synchronized block
【在 i**p 的大作中提到】 : I have the same question as this. : -------------------------------------------- : I am confused a bit about wait and notify/notifyall. : I know there is a lock for every java object. I know wait will release the : lock for other thread. How about notify/notifyall? Does notify/notifyall : realse the lock it is holding for other thread? : ------------------------------------------------- : There are 2 different answers for it on this link : http://stackoverflow.com/questions/5999193/java-wait-notify-not : Could anyone here tell me which one is the right answer?
|
i**p 发帖数: 902 | 3 For the example below, if "lock.notify();" on thread B wakes up the thread A
but does not give up the lock, how does the thread A re-claim the lock and
start running?
More clear, can code_A run right after lock.notify(); or have to wait until
code_B is done?
Thread A
synchronized (lock)
{ ...
while ...
lock.wait();
code_A
....
}
Thread B
synchronized (lock)
{ ...
lock.notify();
code_B
}
thread
【在 s*******e 的大作中提到】 : They only wake up blocked thread, the monitor is not released by the thread : until the end of the synchronized block
|
e*****t 发帖数: 1005 | 4 if thread A is in waiting because of your lock.wait(), then thread A already
has the lock. How come thread B can obtian the lock and call the notify()?
A
and
until
【在 i**p 的大作中提到】 : For the example below, if "lock.notify();" on thread B wakes up the thread A : but does not give up the lock, how does the thread A re-claim the lock and : start running? : More clear, can code_A run right after lock.notify(); or have to wait until : code_B is done? : Thread A : synchronized (lock) : { ... : while ... : lock.wait();
|
s*******e 发帖数: 3042 | 5 The lock is released by calling wait()
already
)?
【在 e*****t 的大作中提到】 : if thread A is in waiting because of your lock.wait(), then thread A already : has the lock. How come thread B can obtian the lock and call the notify()? : : A : and : until
|
s*******e 发帖数: 3042 | 6 Thread A will just block till thread B completes and releases the lock.
A
and
until
【在 i**p 的大作中提到】 : For the example below, if "lock.notify();" on thread B wakes up the thread A : but does not give up the lock, how does the thread A re-claim the lock and : start running? : More clear, can code_A run right after lock.notify(); or have to wait until : code_B is done? : Thread A : synchronized (lock) : { ... : while ... : lock.wait();
|
i**p 发帖数: 902 | 7 My testing result seems the code_A can be started running right away once
the notify() is called on Android emulator.
Has you "snowslope" checked the link I provide? Any comment?
【在 s*******e 的大作中提到】 : Thread A will just block till thread B completes and releases the lock. : : A : and : until
|
s*******e 发帖数: 3042 | 8 The javadoc says clearly the woken thread has to wait to obtain the monitor
before it can enter the critical section. So what's the confusion?
Not sure what you meant by 'right away'. How long do you expect it to wait
if code_B only takes one nanosec to finish?
【在 i**p 的大作中提到】 : My testing result seems the code_A can be started running right away once : the notify() is called on Android emulator. : Has you "snowslope" checked the link I provide? Any comment?
|
g*****g 发帖数: 34805 | 9 Yes, it runs right away (unblocked from the wait call), but the thread
can only obtain the lock after the other thread finishes the critical
section.
The lock is released when the other thread finishes the critical section.
monitor
【在 s*******e 的大作中提到】 : The javadoc says clearly the woken thread has to wait to obtain the monitor : before it can enter the critical section. So what's the confusion? : Not sure what you meant by 'right away'. How long do you expect it to wait : if code_B only takes one nanosec to finish?
|
i**p 发帖数: 902 | 10 Thank you 2 to join the discussion. Let me make some changes to my example
code and make the code_B takes more time.
1. Is it possible that code_A starts running after lock.notify() but before
the for loop is done?
2. When does thread B release the lock, after lock.notify() or after end_of_
critical?
All of us agree the answer is "after end_of_critical", right?
3. If the answer for Q1 is "Yes", how can code_A run when the lock is still held by another thread, because the thread B will not release the lock until it reaches to end_of_critical ?
Thread A
synchronized (lock)
{ ...
while ...
lock.wait();
code_A
....
}
Thread B
synchronized (lock)
{ ...
lock.notify();
// code_B
for (int i=0; i<=65535; i++);
} // end_of_critical
【在 g*****g 的大作中提到】 : Yes, it runs right away (unblocked from the wait call), but the thread : can only obtain the lock after the other thread finishes the critical : section. : The lock is released when the other thread finishes the critical section. : : monitor
|
r*****l 发帖数: 2859 | 11 Since you have the code, you should be able to run it and know the answers
to your questions. Seems that you are testing others :)
A will wait until B finishes the loop.
B releases the lock after the sync block.
To answer your question 3, you need to understandthe thread states. When A calls
wait(), A is put in the WAITING state. It will wait until a notify() or
notifyAll(). When that happens, A is NOT put int the RUNNABLE state, but
BLOCKED state. A waits for the lock in the BLOCKED state. When B exit the
critical block. A is put from BLOCKED state into RUNNABLE state.
before
of_
still held by another thread, because the thread B will not release the lock
until it reaches to end_of_critical ?
【在 i**p 的大作中提到】 : Thank you 2 to join the discussion. Let me make some changes to my example : code and make the code_B takes more time. : 1. Is it possible that code_A starts running after lock.notify() but before : the for loop is done? : 2. When does thread B release the lock, after lock.notify() or after end_of_ : critical? : All of us agree the answer is "after end_of_critical", right? : 3. If the answer for Q1 is "Yes", how can code_A run when the lock is still held by another thread, because the thread B will not release the lock until it reaches to end_of_critical ? : Thread A : synchronized (lock)
|
s*******e 发帖数: 3042 | 12 Just put aside the wait/notify scenario and think what happens when one
thread tries to obtain a lock but finds it under possession of another
thread -- it will block until the first one passes the critical section and
releases the lock.
This is exactly what happens after thread A wakes up while B still holds the
lock.
before
of_
still held by another thread, because the thread B will not release the lock
until it reaches to end_of_critical ?
【在 i**p 的大作中提到】 : Thank you 2 to join the discussion. Let me make some changes to my example : code and make the code_B takes more time. : 1. Is it possible that code_A starts running after lock.notify() but before : the for loop is done? : 2. When does thread B release the lock, after lock.notify() or after end_of_ : critical? : All of us agree the answer is "after end_of_critical", right? : 3. If the answer for Q1 is "Yes", how can code_A run when the lock is still held by another thread, because the thread B will not release the lock until it reaches to end_of_critical ? : Thread A : synchronized (lock)
|
i**p 发帖数: 902 | 13 Thank you! The topic is well discussed.
Because the lock.wait() gives up the lock, some of us assume lock.notify()
releases the lock too.
The confuse
calls
【在 r*****l 的大作中提到】 : Since you have the code, you should be able to run it and know the answers : to your questions. Seems that you are testing others :) : A will wait until B finishes the loop. : B releases the lock after the sync block. : To answer your question 3, you need to understandthe thread states. When A calls : wait(), A is put in the WAITING state. It will wait until a notify() or : notifyAll(). When that happens, A is NOT put int the RUNNABLE state, but : BLOCKED state. A waits for the lock in the BLOCKED state. When B exit the : critical block. A is put from BLOCKED state into RUNNABLE state. :
|
h*********e 发帖数: 247 | 14 try this, all clear.
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadExample
{
public static volatile AtomicInteger count = new AtomicInteger(0);
public static Object lock = new Object();
/**
* @param args
*/
public static void main(String[] args)
{
Runnable a = new Runnable() {
@Override
public void run()
{
synchronized(lock)
{
System.out.println("A thread obtains lock");
while(count.get() != 1)
{
try
{
System.out.println("A thread sees counter as "
+ count.get());
System.out.println("A thread put to wait");
lock.wait();
System.out.println("A thread woke up");
System.out.println("A thread sees counter as "
+ count.get());
}
catch(InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
Runnable b = new Runnable() {
@Override
public void run()
{
// while(true)
{
synchronized(lock)
{
System.out.println("B thread sees counter as " +
count.get());
lock.notify();
System.out.println("B thread wakes up A");
System.out.println("B thread updates counter to " +
count.incrementAndGet());
for(int i = 0; i < 3; i++)
{
try
{
Thread.currentThread().sleep(1000);
System.out.println("B thread keeps working!"
);
}
catch(InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("B thread done!");
}
}
}
};
new Thread(a).start();
new Thread(b).start();
}
} |