黑马程序员技术交流社区

标题: 关于多线程的同步和唤醒机制的一个疑问 [打印本页]

作者: zd12345    时间: 2014-10-17 21:21
标题: 关于多线程的同步和唤醒机制的一个疑问
关于多线程的同步机制和唤醒机制的疑问:比如有两个线程A和B,它们有一个同步代码块,锁为对象r,当线程A进入同步代码块时,线程B等待在同步代码块外。当线程A中执行代码r.wait()时,A线程进入冻结状态,但代码还是停在同步代码块中,这时是不是A线程会放弃对锁r的拥有?而此时B线程进入同步代码块,如果在B中执行代码r.notify(),这时A线程是立刻被激活吗?激活后是从休眠后的位置接着向下执行代码吗?如果此时线程B还在同步代码块中,那不就会出现线程A和B同时进入同步代码块中的现象吗?? 大神求解
作者: zd12345    时间: 2014-10-17 21:58
大神们在哪里啊!!
作者: 刘家斌    时间: 2014-10-17 22:23
你这个理解错了,既然两个线程执行的是同一个代码块,在让线程等待有什么意义吗?等待是多个线程对同一个资源进行操作,但操作的动作不一样,同时需要轮流执行不同的操作时用到的。
作者: 罗林军    时间: 2014-10-17 22:50
楼主,执行同一个同步代码块,A线程停在同步代码块里面的时候是没有释放锁的,B线程过来判断锁的时候会发现锁里面有人,B线程进不去的。为了方便理解,楼主可以考虑,如果没有等待唤醒的时候,因为CPU执行的时候线程也是不确定的,假设出现情况A停在同步代码块里面,这时候B来了就会判断同步代码块里面有没有人,有的话就进不去的,这也是同步加锁的作用啊
作者: 夕默    时间: 2014-10-17 22:58
你贴个代码来看看啊!被你绕晕了!
作者: 哈达洋    时间: 2014-10-17 22:58
本帖最后由 哈达洋 于 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
罗林军 发表于 2014-10-17 22:50
楼主,执行同一个同步代码块,A线程停在同步代码块里面的时候是没有释放锁的,B线程过来判断锁的时候会发现 ...

嗯嗯,我的意思是这样:假设A在wait中,B执行notify将A唤醒,但是B还没有出同步代码块,这时A会立刻执行吗?如果立刻执行,A和B不就同时执行同步块了吗??
作者: 罗林军    时间: 2014-10-18 14:14
本帖最后由 罗林军 于 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
刘家斌 发表于 2014-10-17 22:23
你这个理解错了,既然两个线程执行的是同一个代码块,在让线程等待有什么意义吗?等待是多个线程对同一个资 ...

我的意思是两个线程具有同一个锁的同步快,而不是执行相同的代码块……
作者: 面具猴    时间: 2014-10-18 14:36
对于执行相同代码的线程,只是用互斥作用的synchronized就可以了,用不着wait(),notify()





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2