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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 8047107 高级黑马   /  2013-6-25 19:07  /  2500 人查看  /  13 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 孙百鑫 于 2013-6-30 08:46 编辑

在 Java基础视频教程第11天-09-多线程(多线程的安全问题)  里面售票可能出现负票会出现安全问题.
是因为多线程操作时候可能中间的一个线程处于临时状态,这时候其他进程进来了.后来这个线程正常后也还是操作共享数据导致的.
所以加了同步锁,线程0进来  线程1就进不来了...可以解决这个问题.
这个是没有问题的.....



在  Java基础视频教程第12天-05-多线程(线程间通信-生产者消费者) 这个例子里面

有个resources的类.里面有同步函数,这时候创建两个生产者线程,2个消费者线程,但是同步了为什么生产者0的线程进入了 生产者1的线程还可以进入?已经在函数加锁了啊. 不是线程0有锁进入之后,线程1不就没锁进入不了了么!?
他们的锁都是同一个啊...而且操作的是共享数据啊.(生产出来的商品的编号..)

评分

参与人数 1技术分 +2 收起 理由
袁梦希 + 2 很给力!

查看全部评分

13 个回复

倒序浏览
大牛,看看是不是因为多核CPU的问题
回复 使用道具 举报
万琪 发表于 2013-6-25 20:22
大牛,看看是不是因为多核CPU的问题

前两个字打错了吧??
不是多核..就一般机器..
我是今天看了视频消费者的那个视频 才觉得迷惑
回复 使用道具 举报
顶起来一下
回复 使用道具 举报
很好
回复 使用道具 举报
把 if(flag)改成while(flag) 循环
回复 使用道具 举报
tpsu88 中级黑马 2013-6-26 09:56:27
7#
但是同步了为什么生产者0的线程进入了 生产者1的线程还可以进入?已经在函数加锁了啊.

答:首先t1抢到执行权,此时flag初始值是false,不执行wait,所以生产了一个,再往下他把flag改成了true,然后notify唤醒了其他线程(这就是关键!),t1回头判断if(flag)是true,所以就wait了。
此时t2抢到执行权,判断if,也是真,所以也挂那了!!
所以关键是t1唤醒了其他线程,t2才进来的。并不是t1上来就挂那了!
回复 使用道具 举报
你到底想说什吗              
回复 使用道具 举报
你怎么得的技术分啊   那么高   分享一下
回复 使用道具 举报

我听视频里的意思好像就是一个线程wait之后 其他线程就可以继续了....就像没锁一样 ~
改为解决了把
回复 使用道具 举报
tpsu88 发表于 2013-6-26 09:56
但是同步了为什么生产者0的线程进入了 生产者1的线程还可以进入?已经在函数加锁了啊.

答:首先t1抢到执行 ...

我的意思就是 t1睡了之后 t2是否就可以直接进来?就这个简单的意思.....你误解了
回复 使用道具 举报
主要是wait()的问题,线程读到wait()后就会等待唤醒,并且释放锁。等被唤醒之后再继续强cpu执行权,抢到后接着执行上次wait()后的代码,不会从加锁位置开始读代码的。
回复 使用道具 举报
楼主您好,帖子长时间没有动态我已经将您的帖子改成已解决。如有问题请私密我哦~
回复 使用道具 举报
两点:
|--if:只判断一次
|--notify():随机唤醒任意一个线程

解释:
生产者0进入后,随机唤醒一个线程,生产者1可能被唤醒,进入,由于if只判断一次,生产者1来时条件还满足条件,也进入了,就造成了你说的现象。
解决:
将if判断换成while 循环判断,把notify()方法,换成notifyAll()方法,如果是环形的生产者1,条件不满足就进不来,如果是消费者的就可以。问题会被解决。
优化解决:
使用Lock类来解决。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马