어리석은 질문 일지 모르지만이 클래스의 두 개의 다른 스레드가 단일 ReentrantLock을 사용할 수없는 이유를 이해할 수 없습니다 (사용 된 ArrayBlockingQueue의 단순화 된 솔루션입니다). 스레드와 잠금 장치)와 재생 :ArrayBlockingQueue의 두 스레드가 ReentrantLock을 취득 할 수있는 이유는 무엇입니까?
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
...
나는 그것이 조건의 내가 왜 발생합니까 이해할 수없는 논리적주기 동안의 사용 때문이 아니라 용의자 :
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();
}
}
을 나는 콘솔에서이 결과를받을 . 설명에 감사드립니다. 감사!