Java 同步中的不同状态

Java 同步中的不同状态,java,Java,我有两条线thread1和thread2 线程内1 synchronized(lock) { lock.wait(); if(lock == null) {execute1} if(lock != null) {execute2} } 在thread2内 synchronized(lock) { lock.notify(); lock = null; } 首先调用thread1,

我有两条线thread1和thread2

线程内1

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

synchronized(lock) {  
    lock.notify();  
    lock = null;  
}  
首先调用thread1,然后调用thread2。
thread1调用wait后,它将释放其锁。和thread2调用notify并将lock设置为null。
现在,当thread1再次尝试获取锁时,为什么不抛出任何异常。由于lock设置为null,thread1尝试获取该锁,因此在尝试获取锁时不应该引发null指针异常。

若它并没有抛出任何异常,那个么thread1仍在读取lock value not null。那么它不应该执行语句{execute2}吗

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

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

然后,当thread1重新获得控制权时将调用execute1,因为变量在该点为null

编辑 由于您似乎误解了整个
wait()
notify()
语义,下面是(我的重点部分)的相关引用:

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


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

在哪里声明了
lock
?它是
Runnable
/
Thread
扩展类的实例变量吗?它是该方法的局部变量吗?我们需要更多关于代码的详细信息。如果
lock
确实是
null
,那么您的
lock.wait()
将抛出一个NPE。在任何情况下,都是在
lock
上同步,然后将其设置为
null
。发生这种情况时,无法保证对
lock
所做更改的可见性。您应该在
final
对象上同步。lock是主类a中object类型的实例变量。lock=new object();两个线程都扩展了runnable。我从同一个类A启动两个线程。首先调用thread1,然后调用thread2。如果一个线程收到通知,它不应该再次获取锁。如果它应该获取一个锁,它将使用什么对象,它会尝试获取同步块中变量引用的对象上的锁(同步块中的lock引用的对象(lock)),还是在调用wait的瞬间尝试获取变量引用的对象上的锁(调用lock.wait()时被lock引用的对象)@vjk:在调用
wait()
将控制权返回给方法之前,它再次获得锁。该变量仅用于确定要调用哪个对象
wait()
(就像调用任何其他实例方法一样!),显然
wait()
不知道您的方法的局部变量。请查看javadoc以了解。