A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© zd12345 中级黑马   /  2014-10-17 21:21  /  1608 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

关于多线程的同步机制和唤醒机制的疑问:比如有两个线程A和B,它们有一个同步代码块,锁为对象r,当线程A进入同步代码块时,线程B等待在同步代码块外。当线程A中执行代码r.wait()时,A线程进入冻结状态,但代码还是停在同步代码块中,这时是不是A线程会放弃对锁r的拥有?而此时B线程进入同步代码块,如果在B中执行代码r.notify(),这时A线程是立刻被激活吗?激活后是从休眠后的位置接着向下执行代码吗?如果此时线程B还在同步代码块中,那不就会出现线程A和B同时进入同步代码块中的现象吗?? 大神求解

评分

参与人数 1黑马币 +1 收起 理由
杨佳名 + 1

查看全部评分

9 个回复

倒序浏览
大神们在哪里啊!!
回复 使用道具 举报
你这个理解错了,既然两个线程执行的是同一个代码块,在让线程等待有什么意义吗?等待是多个线程对同一个资源进行操作,但操作的动作不一样,同时需要轮流执行不同的操作时用到的。
回复 使用道具 举报
楼主,执行同一个同步代码块,A线程停在同步代码块里面的时候是没有释放锁的,B线程过来判断锁的时候会发现锁里面有人,B线程进不去的。为了方便理解,楼主可以考虑,如果没有等待唤醒的时候,因为CPU执行的时候线程也是不确定的,假设出现情况A停在同步代码块里面,这时候B来了就会判断同步代码块里面有没有人,有的话就进不去的,这也是同步加锁的作用啊
回复 使用道具 举报
你贴个代码来看看啊!被你绕晕了!
回复 使用道具 举报
本帖最后由 哈达洋 于 2014-10-17 23:05 编辑

wait()方法一执行,就会释放锁,这恰恰也是和sleep()方法的一个区别所在,sleep()方法是不释放锁的。下面是源代码中的部分注释:
The current thread must own this object's monitor. The thread
     * releases ownership of this monitor and waits until another thread
     * notifies threads waiting on this object's monitor to wake up
     * either through a call to the {@code notify} method or the
     * {@code notifyAll} method.



回复 使用道具 举报
zd12345 中级黑马 2014-10-18 14:00:04
7#
罗林军 发表于 2014-10-17 22:50
楼主,执行同一个同步代码块,A线程停在同步代码块里面的时候是没有释放锁的,B线程过来判断锁的时候会发现 ...

嗯嗯,我的意思是这样:假设A在wait中,B执行notify将A唤醒,但是B还没有出同步代码块,这时A会立刻执行吗?如果立刻执行,A和B不就同时执行同步块了吗??
回复 使用道具 举报
本帖最后由 罗林军 于 2014-10-18 14:26 编辑
zd12345 发表于 2014-10-18 14:00
嗯嗯,我的意思是这样:假设A在wait中,B执行notify将A唤醒,但是B还没有出同步代码块,这时A会立刻执行 ...

楼主的意思是A在执行wait的时候也是在同步代码块里面?这样的话确实B能够进入同步代码块,因为wait的时候会释放锁,这时候执行notify将A唤醒A也确实会去执行同步代码块里面内容造成同步数据错乱,所有我们在同步代码块里面wait的话都是循环判断的,楼主可以看看生产者消费者模式的代码,里面就是通过循环判断标记避免这类问题的
回复 使用道具 举报
zd12345 中级黑马 2014-10-18 14:27:26
9#
刘家斌 发表于 2014-10-17 22:23
你这个理解错了,既然两个线程执行的是同一个代码块,在让线程等待有什么意义吗?等待是多个线程对同一个资 ...

我的意思是两个线程具有同一个锁的同步快,而不是执行相同的代码块……
回复 使用道具 举报
对于执行相同代码的线程,只是用互斥作用的synchronized就可以了,用不着wait(),notify()
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马