来自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} }}
我错过了什么?