调用notify()后什么时候真正释放锁

At what point is the lock really released after calling notify()

我有我检查过的代码,我只是想知道我的理解是否正确。我有以下两个 类

public class WaitCheckWaiter implements Runnable
{

WaitCheck wc;

public WaitCheckWaiter( WaitCheck wc )
{
    this.wc = wc;
}

@Override
public void run()
{
    synchronized ( wc.strList )
    {
        wc.strList.add( "Added" );
        System.out.println( "Notify for others" );
        wc.strList.notifyAll();
        for ( int i = 0; i < 100; i++ )
        {
            System.out.println( i );
        }
        try
        {
            Thread.sleep( 5000 );
        }
        catch ( InterruptedException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println( "Woke up" );
        System.out.println( "After Notifying" );
    }
    System.out.println( "After synch WaitCheckWaiter" );

}

}

然后下面这个

public class WaitCheck implements Runnable{

WaitCheck wc;
List<String> strList = new ArrayList();

public static void main(String[] args) {
    WaitCheck wc = new WaitCheck();
    new Thread(wc).start();
    WaitCheckWaiter wcw = new WaitCheckWaiter(wc);
    new Thread(wcw).start();
}



@Override
public void run() {
    synchronized (strList) {
        if(strList.size() == 0)
        {
            try {
                System.out.println("Just Before wait..");
                strList.wait();
                System.out.println("Just after wait..");
                // printing the added value
                System.out.println("Value : "+strList.get(0));
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        else
        {
            System.out.println("In else statement..!!");
        }
    }
    System.out.println("After synch WaitCheck");

}

}

所以我的理解是,即使我调用了notifyAll(),等待线程也无法恢复,直到调用了notifyAll()的同步块完成。这是正确的还是有任何其他 none 确定性行为。

Javadoc for the Object.notifyAll method 对这个话题说的很清楚:

(我加粗的文字)

Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the wait methods.

The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object. The awakened threads will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened threads enjoy no reliable privilege or disadvantage in being the next thread to lock this object.

添加到另一个答案,来自关于 Thread.sleep(...) 的文档:

线程不会失去任何监视器的所有权。

意味着至少作为一项基本原则,人们应该永远不会调用Thread.sleep(...)只要任何同步锁仍在持有。

在大多数操作系统中,线程由一个对象表示,该对象可以根据其状态在不同容器之间移动。这些容器传统上称为 "queues",尽管它们不一定实现为实际的先进先出队列。

当线程调用 o.wait() 时,它的对象从 "currently running" 队列移动到仅包含等待 o.notify() 的那些对象的队列。当另一个线程调用 o.notify() 时,操作系统从该队列中选择一个线程,并将其移动到等待轮到他们进入(或 return 到) synchronized(o) 块的线程队列.

这几乎是 o.notify() 所做的事情。事实上,如果正在等待 o.notify() 的线程队列是空的,那么 o.notify() 根本不会做任何事情。

o.notifyAll() 是一样的,只是它不是只移动一个线程,而是移动所有正在等待的线程。