【发布时间】:2015-02-22 07:23:02
【问题描述】:
我想知道如果我们将底层数据结构更改为像java.util.LinkedList 这样的非线程安全列表,为什么LinkedBlockingQueue 不能工作?当我尝试它时,我得到一个 NoSuchElementException。难道它没有被锁(takeLock)保护,这使它成为线程安全的吗?
private final List<E> list;
private final ReentrantLock takeLock;
private final ReentrantLock putLock;
private final Condition notFull;
private final Condition notEmpty;
private final AtomicInteger count;
public LinkedBlockingQueue() {
takeLock = new ReentrantLock();
putLock = new ReentrantLock();
notFull = putLock.newCondition();
notEmpty = takeLock.newCondition();
count = new AtomicInteger(0);
list = new LinkedList<E>();
}
public E get() {
E item = null;
int c = -1;
try {
takeLock.lockInterruptibly();
while (count.get() == 0) notEmpty.await();
// original -> item = dequeue();
item = list.remove(); // NoSuchElementException
c = count.getAndDecrement();
}
catch (InterruptedException ie) {}
finally {
takeLock.unlock();
}
if (c == capacity) signalNotFull();
return item;
}
public void put(E e) {
int c = -1;
try {
putLock.lockInterruptibly();
while (count.get() == BOUND_SIZE) notFull.await();
// original -> enqueue(node);
list.add(e);
c = count.getAndIncrement();
}
catch (InterruptedException ie) {}
finally {
putLock.unlock();
}
if (c == 0) signalNotEmpty();
}
【问题讨论】:
-
您如何将项目添加到列表中?
-
count和size和putLock和takeLock有什么区别? -
还有,这和LinkedBlockingQueue有什么关系?
-
您的代码看起来很不安全。 (锁不会神奇地使代码线程安全)
-
这是为什么呢?与原始实现 (docjar.com/html/api/java/util/concurrent/…) 的唯一变化只是切换到 java.util.LinkedList
标签: java multithreading concurrency thread-safety blockingqueue