BG3 Mod Manager:现代化模组管理系统的架构设计与实现
2026/6/6 9:07:33
阻塞队列是线程安全的队列,核心特性:
我会带你实现最经典的有界阻塞队列(基于数组+锁+等待/通知机制),这也是 JDKArrayBlockingQueue的核心原理。
ReentrantLock保证原子操作Condition条件队列(比wait/notify更精准)notEmpty:队列非空,唤醒消费者notFull:队列非满,唤醒生产者importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.ReentrantLock;/** * 基于数组实现的有界阻塞队列 * @param <E> 队列元素类型 */publicclassMyBlockingQueue<E>{// 存储元素的数组privatefinalObject[]items;// 队头指针(取元素用)privateinttakeIndex;// 队尾指针(放元素用)privateintputIndex;// 队列元素数量privateintcount;// 可重入锁:保证入队/出队的线程安全privatefinalReentrantLocklock;// 条件:队列非空(消费者等待/唤醒)privatefinalConditionnotEmpty;// 条件:队列非满(生产者等待/唤醒)privatefinalConditionnotFull;/** * 构造方法:指定队列容量 * @param capacity 队列最大容量 */publicMyBlockingQueue(intcapacity){if(capacity<=0){thrownewIllegalArgumentException("容量必须大于0");}this.items=newObject[capacity];// 默认非公平锁(也可传true创建公平锁)this.lock=newReentrantLock();this.notEmpty=lock.newCondition();this.notFull=lock.newCondition();}/** * 阻塞入队:队列满时阻塞线程 * @param element 入队元素 * @throws InterruptedException 线程中断异常 */publicvoidput(Eelement)throwsInterruptedException{// 加锁:保证原子操作lock.lockInterruptibly();try{// 循环判断:防止虚假唤醒while(count==items.length){// 队列满,生产者阻塞,释放锁等待唤醒notFull.await();}// 入队操作enqueue(element);}finally{// 必须释放锁lock.unlock();}}/** * 阻塞出队:队列空时阻塞线程 * @return 出队元素 * @throws InterruptedException 线程中断异常 */publicEtake()throwsInterruptedException{lock.lockInterruptibly();try{// 循环判断:防止虚假唤醒while(count==0){// 队列空,消费者阻塞,释放锁等待唤醒notEmpty.await();}// 出队操作returndequeue();}finally{lock.unlock();}}/** * 私有入队方法:仅在加锁后调用 */privatevoidenqueue(Eelement){items[putIndex]=element;// 指针循环(数组环形复用)if(++putIndex==items.length){putIndex=0;}count++;// 唤醒一个等待的消费者notEmpty.signal();}/** * 私有出队方法:仅在加锁后调用 */privateEdequeue(){Eelement=(E)items[takeIndex];items[takeIndex]=null;// 帮助GC回收// 指针循环if(++takeIndex==items.length){takeIndex=0;}count--;// 唤醒一个等待的生产者notFull.signal();returnelement;}// 获取队列元素数量publicintsize(){lock.lock();try{returncount;}finally{lock.unlock();}}}while而不是if?必须用循环判断,防止虚假唤醒(线程未被唤醒却自动唤醒),保证队列状态正确。
takeIndex和putIndex到达数组末尾后重置为0,实现数组空间复用,效率更高。
ReentrantLock控制所有操作,保证线程安全Condition精准唤醒:Object.wait/notify效率更高(不会误唤醒不相关线程)。publicclassBlockingQueueTest{publicstaticvoidmain(String[]args){MyBlockingQueue<Integer>queue=newMyBlockingQueue<>(5);// 生产者线程:持续入队newThread(()->{try{for(inti=1;i<=10;i++){queue.put(i);System.out.println("生产者入队:"+i+",队列大小:"+queue.size());Thread.sleep(500);}}catch(InterruptedExceptione){Thread.currentThread().interrupt();}},"生产者").start();// 消费者线程:持续出队newThread(()->{try{while(true){Integerelement=queue.take();System.out.println("消费者出队:"+element+",队列大小:"+queue.size());Thread.sleep(1000);}}catch(InterruptedExceptione){Thread.currentThread().interrupt();}},"消费者").start();}}实际开发直接用 JUC 包下的实现类,无需手写:
java.util.concurrent官方实现while判断队列状态,防止虚假唤醒