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

Java 调用notify()后,锁在什么时候真正释放,java,multithreading,synchronized,Java,Multithreading,Synchronized,我检查了代码,我只想知道我的理解是正确的。我有以下两门课 public class WaitCheckWaiter implements Runnable { WaitCheck wc; public WaitCheckWaiter( WaitCheck wc ) { this.wc = wc; } @Override public void run() { synchronized ( wc.strList ) { wc.strList.add(

我检查了代码,我只想知道我的理解是正确的。我有以下两门课

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类waitcheckwayer实现Runnable
{
等待检查厕所;
公共服务生(服务员厕所)
{
this.wc=wc;
}
@凌驾
公开募捐
{
已同步(wc.strList)
{
wc.strList.添加(“添加”);
System.out.println(“通知他人”);
wc.strList.notifyAll();
对于(int i=0;i<100;i++)
{
系统输出打印LN(i);
}
尝试
{
睡眠(5000);
}
捕捉(中断异常e)
{
//TODO自动生成的捕捉块
e、 printStackTrace();
}
System.out.println(“唤醒”);
System.out.println(“通知后”);
}
System.out.println(“同步后waitcheckwater”);
}
}
然后是下面这个

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");

}

}
public类WaitCheck实现Runnable{
等待检查厕所;
List strList=new ArrayList();
公共静态void main(字符串[]args){
WaitCheck wc=新的WaitCheck();
新螺纹(wc).start();
WaitCheck WaitCheck Waiter wcw=新的服务员(wc);
新线程(wcw).start();
}
@凌驾
公开募捐{
已同步(strList){
if(strList.size()=0)
{
试一试{
System.out.println(“就在等待之前”);
strList.wait();
System.out.println(“刚过等待…”);
//打印附加值
System.out.println(“值:+strList.get(0));
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
其他的
{
System.out.println(“In else语句..!!”;
}
}
System.out.println(“同步后等待检查”);
}
}
因此,我的理解是,即使我调用notifyAll(),等待线程也无法继续,直到同步块完成(称为notifyAll())。这是正确的还是存在其他非确定性行为

在这个话题上,大家都很清楚:

(文本由我加粗)

唤醒在此对象监视器上等待的所有线程。A. 线程通过调用一个wait命令在对象的监视器上等待 方法

唤醒的线程将无法继续,直到 当前线程放弃对该对象的锁定。被唤醒的线程 线程将以通常的方式与任何其他 可能正在积极竞争此对象上的同步;对于 例如,唤醒的线程没有可靠的特权或权限 作为下一个锁定此对象的线程的缺点

在这个问题上,答案非常明确:

(文本由我加粗)

唤醒在此对象监视器上等待的所有线程。A. 线程通过调用一个wait命令在对象的监视器上等待 方法

唤醒的线程将无法继续,直到 当前线程放弃对该对象的锁定。被唤醒的线程 线程将以通常的方式与任何其他 可能正在积极竞争此对象上的同步;对于 例如,唤醒的线程没有可靠的特权或权限 作为下一个锁定此对象的线程的缺点


在另一个答案的基础上,从关于Thread.sleep(…)的文档中添加:

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


这意味着,至少作为一项基本原则,只要同步锁仍然被持有,就应该永远不要调用Thread.sleep(…)。

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

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


这意味着,至少作为一项基本原则,只要同步锁仍被持有,就应该永远不要调用Thread.sleep(…)。

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

当线程调用
o.wait()
时,它的对象将从“当前正在运行”队列移动到只包含那些正在等待
o.notify()
的对象的队列。当另一个线程调用
o.notify()
时,操作系统从该队列中选择一个线程,并将其移动到等待轮到其进入(或返回)已同步(o)块的线程队列中

这几乎是
o.notify()
所做的唯一事情。事实上,如果等待
o.notify()
的线程队列为空,则
o.notify()
根本不做任何事情


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

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

当线程调用
o.wait()
时,它的对象将从“当前正在运行”队列移动到只包含那些正在等待
o.notify()
的对象的队列。当另一个线程调用
o.notify()
时,操作系统从该队列中选择一个线程,并将其移动到等待轮到其进入(或返回)已同步(o)块的线程队列中

这几乎是
o.notify()
所做的唯一事情。实际上,如果等待
o.notify()的线程队列