0

我有两个线程thread1和thread2

在线程1内

synchronized(lock) {  
    lock.wait();  
    if(lock == null)
        {execute1}  
    if(lock != null)  
        {execute2}   
}  

在线程2内

synchronized(lock) {  
    lock.notify();  
    lock = null;  
}  

首先调用thread1,然后调用thread2。
在 thread1 调用 wait 之后,它释放它的锁。并且thread2调用notify并将lock设置为null。
现在,当 thread1 再次尝试获取锁时,为什么它没有抛出任何异常。由于 lock 设置为 null 并且 thread1 尝试获取该锁,因此在尝试获取锁时不应该抛出空指针异常。
如果它没有抛出任何异常,则 thread1 仍在读取锁值不为空。那么它不应该执行语句 {execute2} 吗?

4

1 回答 1

1

您在对象上同步,而不是在变量上同步。监视器属于对象。

如果 lock 指向一个非空对象,然后你等待它,设置lock为 null 并不意味着什么,因为它是被等待并通知的对象指向的对象。lock

然后,当 thread1 重新获得控制权时,将调用 execute1,因为此时变量为空。

编辑

由于您似乎误解了整体wait()和语义,因此这是 Javadocnotify()的相关引用(强调我的):

当前线程必须拥有该对象的监视器。线程释放此监视器的所有权并等待,直到另一个线程通过调用 notify 方法或 notifyAll 方法通知在此对象的监视器上等待的线程唤醒。然后线程等待直到它可以重新获得监视器的所有权并恢复执行。

这应该向您表明该变量在用于指向您同步/等待/通知的对象之前完全不相关。

于 2012-04-18T16:49:08.467 回答