我有一些像这样的代码:
ON DELETE CASCADE
Class ThreadB:
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);
}
}
}
基本上,我有两个线程锁定Threadb对象b。当我运行代码时,我看到:
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();
}
}
}
这里,数字是线程ID,很明显,它们是不同的线程。 此外,它们锁定的对象是相同的(b)。但是,两者都能够进入同步块并等待对象。
怎么可能?
此外,如果我在threadB.run()方法中插入2个其他行:
1
Waiting for b to complete...
22
Waiting for b to complete...
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();
}
}
}
似乎在ThreadB.run()的旧定义中,等待线程错过了通知信号,因此它们无限期地等待。这是对的吗?
此外,如果一个线程在没有调用notify()的情况下退出,则内部释放锁(相当于notifyAll())。是吗?
答案 0 :(得分:5)
因为调用Object.wait()
会释放锁定。来自the documentation:
当前线程必须拥有此对象的监视器。线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。然后该线程等待,直到它可以重新获得监视器的所有权并继续执行。
似乎在ThreadB.run()的旧定义中,等待线程错过了通知信号,因此它们无限期地等待。这是正确的吗? 他们wait()
直到他们notify()
'(可能发生虚假)或者他们被打断。
此外,如果线程退出而未调用notify(),则内部释放锁(相当于notifyAll())。是吗? 线程wait()
后,锁已经被释放。