我在数据库前面使用了LinkedBlockingQueue。一个线程写入队列,另一个从队列读取。

我认为不可能同时进行两次写入。但是一个线程是否有可能同时从队列中读取另一个线程呢?如果没有,是否有Java队列来提供呢?

最佳答案

是的,有可能一个线程正在读取而一个线程正在同时写入。

LinkedBlockingQueue为此使用两个锁。一种用于从队列中取出物品,另一种用于放置物品。

/** Lock held by put, offer, etc */
private final ReentrantLock putLock = new ReentrantLock();

/** Lock held by take, poll, etc */
private final ReentrantLock takeLock = new ReentrantLock();


LinkedBlockingQueue上的实现方式也在其source file (line 77)中进行了讨论。

/*
 * A variant of the "two lock queue" algorithm.  The putLock gates
 * entry to put (and offer), and has an associated condition for
 * waiting puts.  Similarly for the takeLock.  The "count" field
 * that they both rely on is maintained as an atomic to avoid
 * needing to get both locks in most cases. Also, to minimize need
 * for puts to get takeLock and vice-versa, cascading notifies are
 * used. When a put notices that it has enabled at least one take,
 * it signals taker. That taker in turn signals others if more
 * items have been entered since the signal. And symmetrically for
 * takes signalling puts. Operations such as remove(Object) and
 * iterators acquire both locks.
 */

10-06 05:30