收購這可能是一個愚蠢的問題,但我不明白爲什麼一個單一的ReentrantLock可以通過兩個不同的線程在這個類採取(這是我使用ArrayBlockingQueue的簡化解決方案與線程和鎖)玩:爲什麼用條件的ReentrantLock可以通過兩個線程在ArrayBlockingQueue
class SampleThreadSafeQueue {
private ReentrantLock lock = new ReentrantLock();
private List<Integer> list = new ArrayList<>();
private Condition notEmpty;
private Condition notFull;
private volatile int count;
public SampleThreadSafeQueue() {
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}
public int take() {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() +": acquired lock in take()");
while (count == 0) {
notEmpty.await();
}
return extract();
} catch (Exception e) {
e.printStackTrace();
return 0;
} finally {
System.out.println(Thread.currentThread().getName() +": released lock for take()");
lock.unlock();
}
}
private int extract() {
int index = count <= 0 ? 0 : count - 1;
Integer integer = list.get(index);
list.remove(index);
count--;
list.clear();
notFull.signal();
return integer;
}
public void put(int value) {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() +": acquired lock in put()");
while (!list.isEmpty()) {
notFull.await();
}
Thread.sleep(3000); // let's assume it takes 3 secs to add value
insert(value);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() +": released lock for put()");
lock.unlock();
}
}
private void insert(int value) {
list.add(value);
count = list.size();
notEmpty.signal();
}
}
我接受這個結果在控制檯:
pool-1-thread-1: acquired lock in put()
pool-1-thread-1: released lock for put()
pool-1-thread-1: acquired lock in put() - this guy has taken the lock
pool-1-thread-2: acquired lock in take() - that guy has taken the lock as well! wtf?
pool-1-thread-2: released lock for take()
Value = 0
pool-1-thread-2: acquired lock in take()
pool-1-thread-1: released lock for put()
pool-1-thread-1: acquired lock in put()
pool-1-thread-2: released lock for take()
Value = 1
pool-1-thread-1: released lock for put()
pool-1-thread-1: acquired lock in put()
pool-1-thread-2: acquired lock in take()
pool-1-thread-2: released lock for take()
Value = 2
...
我懷疑這是因爲條件的我用while循環,但在邏輯上無法理解爲什麼它會發生。 欣賞你的解釋。謝謝!