论坛首页 Java企业应用论坛

java并发线程-----阻塞队列的实现和思考

浏览 17454 次
精华帖 (3) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (6)
作者 正文
   发表时间:2011-07-05  
samttsch 写道
2中解决方法:

1.使用并发包中的阻塞队列

2.使用两个对象锁,notEmpty,notFull来做(注意顺序)
  不会写,去看温少的并发教程
  
  有空多看看源码,多搜搜资料,别一有问题就问别人


1,并发包中的确实没怎么用过
2,即使做顺序也有可能死锁,温少的里面那个例子我确定会导致死锁 不知道你看清楚了没有或者试过没有 。我说的这个不是问题,我希望你能拿出代码 怎么做好这两个对象锁的顺序然后保证不死锁。
0 请登录后投票
   发表时间:2011-07-05  
xyfwjk 写道
为什么生产工发现仓库没有物品了会去唤醒搬运工,,,,而不是放完产品后再唤醒呢

这个可以放在后头唤醒,也可以放在前面,只要唤醒了就行了,不过我这样放确实好像不太合适。
0 请登录后投票
   发表时间: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值,这个明显不是我们想要的结果
0 请登录后投票
   发表时间: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)
是不可能出现的。
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)
是不可能出现的。

噢 是这样子的,忘记唤醒代码块上还有锁,我搞错了
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);
            }
        }
    }
}
0 请登录后投票
   发表时间:2011-07-05  
我还没写出过会死锁的代码. 想象不出什么样的思维会死锁.
0 请登录后投票
   发表时间: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,死了。所以你这段代码是不行滴。
0 请登录后投票
   发表时间:2011-07-05  
木有看懂楼主想干嘛
就是想写个死锁么
0 请登录后投票
   发表时间:2011-07-05  
p4nny 写道
木有看懂楼主想干嘛
就是想写个死锁么

你得把帖子看完  嘿嘿 不是讨论死锁 不过讨论到这个地方了 就顺便说说而已
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics