阻塞队列BlockingQueue是如何唤醒等待的线程的呢?
创始人
2024-11-15 05:09:22
0

在 Java 中,ConcurrentLinkedQueueArrayBlockingQueueLinkedBlockingQueue 等并发队列通常用于生产者-消费者模式。这些队列使用锁和条件(Condition)来实现线程间的通信。

以下是基于 ArrayBlockingQueue 或 LinkedBlockingQueue 的生产者-消费者模式中,消费者如何知道队列中有元素可用的基本原理:

  1. 锁(Lock): 队列内部维护了一个锁,通常是 ReentrantLock。这个锁用于同步对队列的访问,确保在任何时刻只有一个线程可以修改队列。

  2. 条件(Condition): 锁关联了两个条件,通常称为 notEmpty 和 notFullnotEmpty 条件用于通知消费者队列非空,而 notFull 条件用于通知生产者队列未满。

  3. 消费者等待: 当队列为空时,消费者线程会调用条件 notEmpty 的 await() 方法。这将导致消费者线程释放锁并等待,直到另一个线程(生产者)在队列中插入一个元素并调用 signal() 或 signalAll() 方法来唤醒等待的消费者线程。

  4. 生产者通知: 当生产者向队列中添加一个元素时,它会调用 notEmpty 条件的 signal() 方法来唤醒一个(或所有)等待的消费者线程。

以下是一个简化的例子:

import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;  public class BoundedBuffer {     final Lock lock = new ReentrantLock();     final Condition notEmpty = lock.newCondition();     final Condition notFull = lock.newCondition();     final Object[] items = new Object[100]; // 假设缓冲区大小为100     int putptr, takeptr, count;      public void put(Object x) throws InterruptedException {         lock.lock();         try {             while (count == items.length) // 如果队列已满,则等待                 notFull.await();             items[putptr] = x; // 在这里插入元素             if (++putptr == items.length) putptr = 0;             ++count;             notEmpty.signal(); // 通知消费者队列非空         } finally {             lock.unlock();         }     }      public Object take() throws InterruptedException {         lock.lock();         try {             while (count == 0) // 如果队列为空,则等待                 notEmpty.await();             Object x = items[takeptr]; // 在这里取出元素             if (++takeptr == items.length) takeptr = 0;             --count;             notFull.signal(); // 通知生产者队列未满             return x;         } finally {             lock.unlock();         }     } } 

在这个例子中,消费者在 notEmpty 条件上等待,而生产者在 notFull 条件上等待。当队列状态改变时(例如,生产者添加了一个元素或消费者取出一个元素),相应的条件会被信号唤醒,这样等待的线程就可以重新获取锁并继续执行。

相关内容

热门资讯

微信买链接炸金花房卡/欢乐游大... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享...
微信群开牛牛房卡/冷酷大厅牛牛... 牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受更...
微信群开炸金花房卡在哪购买/微... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
微信群炸金花房卡到哪里买/斗牛... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享...
拼三张房卡链接去哪里买/新人皇... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
微信上玩炸金花房卡怎么买/微信... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
微信牛牛房卡怎样开/新海狮大厅... 牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享受...
微信炸金花链接在哪买房卡/微信... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
在哪里买拼三张微信房卡/新皇豪... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
炸金花如何开好友房间房卡/美猴... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享...
炸金花房卡链接在哪弄的/新九五... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
微信买链接拼三张房卡/橘子大厅... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
微信怎样开炸金房间卡/新猴王微... 牌九是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享受...
斗牛从哪里买房卡/新道游大厅牛... 斗牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受更...
微信链接炸金花房卡在哪买的/斗... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
微信牛牛房卡专卖店联系方式/新... 牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享受...
拼三张好友房卡在哪里买/新大海... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
微信牛牛房间卡在哪买的/老夫子... 斗牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享受...
微信牛牛房卡如何购买/新永和大... 牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享受...
炸金花房间如何购买房卡/微信里... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...