了解BlockingQueue的内存一致性

时间:2016-04-07 16:38:56

标签: java multithreading blockingqueue

来自BlockingQueue documentation

  

内存一致性效果:与其他并发集合一样,   在将对象放入BlockingQueue之前的线程中的操作   发生在访问或删除之后的操作之前   另一个帖子中来自BlockingQueue的元素。'

问题: 这是什么意思?在放置之前有哪些操作?它们是在程序代码中put()调用之前出现的还是什么?

为了提供一些示例,让我们考虑以下将对象发布到共享BlockingQueue

的方法
public class Person{
    private String name;
    private int age;
    //Maybe it's not a good idea to sttore such Date in Person
    //but let's leave it that way
    private Date processingDate;
    //etc..
    //GET, SET, toString
}

public class MyClass{
    private final BlockingQueue<Person> personsToProceed = new LinkedBlockingQueue(1000);

    public void submitPerson(Person p){
         p.setProcessingDate(new Date());
         //Make some other changes on p
         personsToProceed.put(p);
    }

    public void processPerson(){
        Person p = personsToProceed.take();
        //persist it into a DB
    }
}

根据LinkedBlockingQueue.put()实施情况判断,我不会说p.setProcessingDate(new Date());personsToProceed.take();在订单之前保持不变。实际上(评论省略):

public void  put(E e) throws InterruptedException {
        if (e == null) throw new NullPointerException();
        int c = -1;
        final ReentrantLock putLock = this.putLock;
        final AtomicInteger count = this.count;
        putLock.lockInterruptibly();
        try {
            try {
                while (count.get() == capacity)
                    notFull.await();
            } catch (InterruptedException ie) {
                notFull.signal(); // propagate to a non-interrupted thread
                throw ie;
            }
            insert(e);
            c = count.getAndIncrement();
            if (c + 1 < capacity)
                notFull.signal();
        } finally {
            putLock.unlock();
        }
        if (c == 0)
           signalNotEmpty();
  }

我们可以说,put(p)take()之前发生过。但由于p.setProcessingDate(new Date());put(p)不是,take()方法中的processPerson() racy {{1} }}

我错过了什么?

0 个答案:

没有答案