精华帖 (3) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (6)
|
|
---|---|
作者 | 正文 |
发表时间:2011-07-05
samttsch 写道 2中解决方法:
1.使用并发包中的阻塞队列 2.使用两个对象锁,notEmpty,notFull来做(注意顺序) 不会写,去看温少的并发教程 有空多看看源码,多搜搜资料,别一有问题就问别人 1,并发包中的确实没怎么用过 2,即使做顺序也有可能死锁,温少的里面那个例子我确定会导致死锁 不知道你看清楚了没有或者试过没有 。我说的这个不是问题,我希望你能拿出代码 怎么做好这两个对象锁的顺序然后保证不死锁。 |
|
返回顶楼 | |
发表时间:2011-07-05
xyfwjk 写道 为什么生产工发现仓库没有物品了会去唤醒搬运工,,,,而不是放完产品后再唤醒呢
这个可以放在后头唤醒,也可以放在前面,只要唤醒了就行了,不过我这样放确实好像不太合适。 |
|
返回顶楼 | |
发表时间:2011-07-05
AngelAndAngel 写道 blackbeans 写道 看了你的代码其实就是一个生产者消费者问题,不过你对待临界条件时候后的处理貌似有问题,应该使用while(xxx.size()==0) obj.wait();而不是用if做一次判断,这样来做,因为当使用notifyAll时唤醒的线程这个时候不知道是否还满足xxx.size()==0的条件,肯能造成仓库没有货而取出货的情况
你前面一句话是对的 这只是个示例 后句话你自己用程序试试就知道了。 楼主把linkedList.add(object); 放在notifyAll后面确实会出现AngelAndAngel说的情况,因为当时两个线程是竞争的,有可能出现linkedList还没有add的时候先被搬运工搬走(此时list大小为0),linkedList.poll虽然不会抛出异常但是会返回null值,这个明显不是我们想要的结果 |
|
返回顶楼 | |
发表时间:2011-07-05
最后修改:2011-07-05
kakaluyi 写道 AngelAndAngel 写道 blackbeans 写道 看了你的代码其实就是一个生产者消费者问题,不过你对待临界条件时候后的处理貌似有问题,应该使用while(xxx.size()==0) obj.wait();而不是用if做一次判断,这样来做,因为当使用notifyAll时唤醒的线程这个时候不知道是否还满足xxx.size()==0的条件,肯能造成仓库没有货而取出货的情况
你前面一句话是对的 这只是个示例 后句话你自己用程序试试就知道了。 楼主把linkedList.add(object); 放在notifyAll后面确实会出现AngelAndAngel说的情况,因为当时两个线程是竞争的,有可能出现linkedList还没有add的时候先被搬运工搬走(此时list大小为0),linkedList.poll虽然不会抛出异常但是会返回null值,这个明显不是我们想要的结果 不会啊 ,你看一下,这都是用的notEmpty同步锁,假如生产对象还持有这个锁对象,那么搬运工的对象是不可能得到notEmpty对象锁的,所以那个时候不可能去poll的。所以 引用 有可能出现linkedList还没有add的时候先被搬运工搬走(此时list大小为0) |
|
返回顶楼 | |
发表时间:2011-07-05
AngelAndAngel 写道 kakaluyi 写道 AngelAndAngel 写道 blackbeans 写道 看了你的代码其实就是一个生产者消费者问题,不过你对待临界条件时候后的处理貌似有问题,应该使用while(xxx.size()==0) obj.wait();而不是用if做一次判断,这样来做,因为当使用notifyAll时唤醒的线程这个时候不知道是否还满足xxx.size()==0的条件,肯能造成仓库没有货而取出货的情况
你前面一句话是对的 这只是个示例 后句话你自己用程序试试就知道了。 楼主把linkedList.add(object); 放在notifyAll后面确实会出现AngelAndAngel说的情况,因为当时两个线程是竞争的,有可能出现linkedList还没有add的时候先被搬运工搬走(此时list大小为0),linkedList.poll虽然不会抛出异常但是会返回null值,这个明显不是我们想要的结果 不会啊 ,你看一下,这都是用的notEmpty同步锁,假如生产对象还持有这个锁对象,那么搬运工的对象是不可能得到notEmpty对象锁的,所以那个时候不可能去poll的。所以 引用 有可能出现linkedList还没有add的时候先被搬运工搬走(此时list大小为0) 噢 是这样子的,忘记唤醒代码块上还有锁,我搞错了 |
|
返回顶楼 | |
发表时间:2011-07-05
public class BlockingQ
{ private Object notEmpty = new Object(); private Object notFull = new Object(); private Queue<Object> linkedList = new LinkedList<Object>(); private int maxlength = 10; public Object take() throws InterruptedException{ synchronized (notEmpty){ if(linkedList.size()==0) { notEmpty.wait(); } synchronized (notFull){ if(linkedList.size() == maxlength){ notFull.notifyAll(); } return linkedList.poll(); } } } public Object offer(Object object) throws InterruptedException{ synchronized (notEmpty){ if(linkedList.size()==0) { notEmpty.notifyAll(); } synchronized (notFull){ if(linkedList.size() == maxlength){ notFull.wait(); } return linkedList.add(object); } } } } |
|
返回顶楼 | |
发表时间:2011-07-05
我还没写出过会死锁的代码. 想象不出什么样的思维会死锁.
|
|
返回顶楼 | |
发表时间:2011-07-05
最后修改:2011-07-05
samttsch 写道 public class BlockingQ
{ private Object notEmpty = new Object(); private Object notFull = new Object(); private Queue<Object> linkedList = new LinkedList<Object>(); private int maxlength = 10; public Object take() throws InterruptedException{ synchronized (notEmpty){ if(linkedList.size()==0) { notEmpty.wait(); } synchronized (notFull){ if(linkedList.size() == maxlength){ notFull.notifyAll(); } return linkedList.poll(); } } } public Object offer(Object object) throws InterruptedException{ synchronized (notEmpty){ if(linkedList.size()==0) { notEmpty.notifyAll(); } synchronized (notFull){ if(linkedList.size() == maxlength){ notFull.wait(); } return linkedList.add(object); } } } } 这段代码是死锁的示例代码。哈哈。当A线程到达take的时候,发觉linkedList.size()==0,然后开始wait,等待释放notEmpty上的锁,这个时候B线程到达offer,开始add,add了几次后,发觉已到上线,然后wait,等待释放notFull上的锁,但是要释放notFull上的锁,必须要先进入take的notEmpty锁,而notEmpty锁,也在等待offer中的notEmpty锁释放,ok,死了。所以你这段代码是不行滴。 |
|
返回顶楼 | |
发表时间:2011-07-05
木有看懂楼主想干嘛
就是想写个死锁么 |
|
返回顶楼 | |
发表时间:2011-07-05
p4nny 写道 木有看懂楼主想干嘛
就是想写个死锁么 你得把帖子看完 嘿嘿 不是讨论死锁 不过讨论到这个地方了 就顺便说说而已 |
|
返回顶楼 | |