为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕姐4208626 2021-11-17 14:57:24
我有我检查过的代码,我只想知道我的理解是正确的。我有以下两节课public class WaitCheckWaiter implements Runnable{WaitCheck wc;public WaitCheckWaiter( WaitCheck wc ){    this.wc = wc;}@Overridepublic 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();}@Overridepublic 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() 的同步块完成。这是正确的还是有任何其他非确定性行为。
查看完整描述

3 回答

?
largeQ

TA贡献2039条经验 获得超7个赞

方法JavadocObject.notifyAll在这个主题上非常清楚:

(文字由我加粗)

唤醒在此对象监视器上等待的所有线程。线程通过调用等待方法之一在对象的监视器上等待。

被唤醒的线程将无法继续,直到当前线程放弃对该对象的锁定。被唤醒的线程将以通常的方式与可能正在积极竞争以同步此对象的任何其他线程进行竞争;例如,被唤醒的线程在成为下一个锁定该对象的线程时不享有可靠的特权或劣势。


查看完整回答
反对 回复 2021-11-17
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

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

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

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

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


查看完整回答
反对 回复 2021-11-17
?
蛊毒传说

TA贡献1895条经验 获得超3个赞

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

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

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


查看完整回答
反对 回复 2021-11-17
  • 3 回答
  • 0 关注
  • 179 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信