关于生产者和消费者方法中包裹 signalAll() 的 if 语句的疑问
来源:4-8 如果被问偏向锁、轻量级锁、重量级锁

HotChoc
2021-05-27
问题
- 生产者和消费者方法中包裹 signalAll() 的 if 语句的疑问
为什么要在 queue.size() == 1 和 queue.size() == MAX - 1 的时候再去 signalAll() 呢?add() 和 remove() 完之后应该不需要判断 queue.size() 就可以 signalAll() 了吧?// Producer public void readDb() throws InterruptedException { var data = readData(); // 1s lock.lock(); if (queue.size() == MAX) { notFull.await(); return; } queue.add(data); if(queue.size() == 1) { notEmpty.signalAll(); } lock.unlock(); } // Comsumer public void calculate() throws InterruptedException { lock.lock(); if(queue.size() == 0) { notEmpty.await(); return; } var data = queue.remove(); System.out.println("queue-size:" + queue.size()); if(queue.size() == MAX-1) { notFull.signalAll(); } data *= 100; lock.unlock(); }
- await() 后为什么要接着 return?应该可以直接执行下面的步骤吧?
我的代码
这是我的代码,运行也没有发生死锁,请老师指教下上述两个问题,谢谢!
void readDb() {
lock.lock();
try {
while (queue.size() == CAPACITY) {
// await() 会释放当前 Condition 绑定的锁
full.await();
}
int data = readData();
queue.offer(data);
System.out.println(Thread.currentThread().getName() + " read " + data + ", size: " + queue.size());
empty.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
void calculate() {
lock.lock();
try {
while (queue.isEmpty()) {
// await() 会释放当前 Condition 绑定的锁
empty.await();
}
Integer data = queue.poll();
System.out.println(Thread.currentThread().getName() + " calculate " + data + ", size: " + queue.size());
full.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
写回答
1回答
-
求老仙
2021-05-30
你提的两个问题之所以会有判断主要是性能考虑,await/wait这些最终最终都是很复杂的操作。比起一行判断来说,更消耗资源。
10
相似问题
老师什么时候分析下红包的设计方案
回答 2
关于接口中的default关键字
回答 1