[英]How can two threads enter two synchronized blocks which hold a lock on the same object
I have some code like this: 我有一些这样的代码:
public class HelloWorld {
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
Runnable a = new Runnable(){
public void run(){
System.out.println(Thread.currentThread().getId());
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
};
(new Thread(a)).start();
synchronized(b){
System.out.println(Thread.currentThread().getId());
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
}
Class ThreadB: ThreadB类:
class ThreadB extends Thread{
int total;
@Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
System.out.println("Total is: " + total);
notify();
}
}
}
Basically, I have two threads which lock on the Threadb object b. 基本上,我有两个线程锁定Threadb对象b。 When I run the code, I see: 运行代码时,我看到:
1
Waiting for b to complete...
22
Waiting for b to complete...
Here, the numbers are the thread ids, so clearly, they are different threads. 在这里,数字是线程ID,因此很明显,它们是不同的线程。 Also, the object they are locking on is the same(b). 同样,他们锁定的对象是相同的(b)。 However, both are able to enter the synchronized block and wait on the object. 但是,两者都可以进入同步块并等待对象。
How's it possible? 怎么可能
Moreover, if I insert 2 other lines in the threadB.run() method: 此外,如果我在threadB.run()方法中插入其他2行:
class ThreadB extends Thread{
int total;
@Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
System.out.println("Total is: " + total);
notify();
}
}
}
The 2 threads run to completion: 2个线程运行完毕:
Total is: 4950
22
1
Waiting for b to complete...
Waiting for b to complete...
Total is: 4950
Total is: 4950
It seems that in the older definition of ThreadB.run(), a notify signal was missed by the waiting threads, so they wait indefinitely. 似乎在较旧的ThreadB.run()定义中,等待线程错过了一个通知信号,因此它们无限期地等待。 Is it correct? 这是正确的吗?
Also, if a thread exits without calling notify(), the lock gets released intrinsically (equivalent to notifyAll()). 同样,如果线程退出而未调用notify(),则该锁将被内在释放(等效于notifyAll())。 Is that right? 那正确吗?
Because calling Object.wait()
releases the lock. 因为调用Object.wait()
会释放锁定。 From the documentation : 从文档中 :
The current thread must own this object's monitor. 当前线程必须拥有该对象的监视器。 The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. 线程释放此监视器的所有权,并等待直到另一个线程通过调用notify方法或notifyAll方法通知等待在此对象监视器上等待的线程唤醒。 The thread then waits until it can re-obtain ownership of the monitor and resumes execution. 然后,线程等待,直到它可以重新获得监视器的所有权并恢复执行。
It seems that in the older definition of ThreadB.run(), a notify signal was missed by the waiting threads, so they wait indefinitely. 似乎在较旧的ThreadB.run()定义中,等待线程错过了一个通知信号,因此它们无限期地等待。 Is it correct? 这是正确的吗? They wait()
until they are notify()
'd (which can happen spuriously) or they are interrupted. 它们wait()
直到被notify()
终止(这可能是虚假的)或被中断。
Also, if a thread exits without calling notify(), the lock gets released intrinsically (equivalent to notifyAll()). 同样,如果线程退出而未调用notify(),则该锁将被内在释放(等效于notifyAll())。 Is that right? 那正确吗? Once a thread is wait()
ing, the lock is already released. 一旦线程正在wait()
,锁就已经释放。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.