• Java实现阻塞队列


    使用Condition实现简单的阻塞队列

    阻塞队列是一种特殊的先进先出队列,它有以下几个特点
    1.入队和出队线程安全
    2.当队列满时,入队线程会被阻塞;当队列为空时,出队线程会被阻塞。

    import java.util.LinkedList;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * @author: MXD
     * @date: 2021/8/12 17:10
     * @description: 实现简单的阻塞队列
     */
    public class MyBlockingQueue<E> {
        /**
         * 阻塞队列最大容量
         */
        private int size;
    
        /**
         * 队列底层实现
         */
        LinkedList<E> list = new LinkedList<>();
    
        ReentrantLock lock = new ReentrantLock();
    
        /**
         * 队列满的等待条件
         */
        Condition full = lock.newCondition();
    
        /**
         * 队列空的等待条件
         */
        Condition empty = lock.newCondition();
    
        public MyBlockingQueue(int size) {
            this.size = size;
        }
    
    
        public void enqueue(E e) throws InterruptedException {
            lock.lock();
            try {
                // 队列满了,就在full条件上进行等待
                while (list.size() == size){
                    full.await();
                }
    
                list.add(e);
                System.out.println("入队:"+e);
                // 入队之后,就通知在empty条件下等待的线程
                empty.signal();
            } finally {
                lock.unlock();
            }
        }
    
        public E dequeue() throws InterruptedException {
            E e;
            lock.lock();
            try {
                // 队列为空,就在空条件上等待
                while (list.size() == 0){
                    empty.await();
                }
                e = list.removeFirst();
                System.out.println("出队:"+e);
                // 出队之后,就通知在full条件下等待的线程
                full.signal();
                return e;
            } finally {
                lock.unlock();
            }
        }
    }
    
    

    测试

    package com.md.lock;
    
    /**
     * @author: MXD
     * @date: 2021/8/12 17:28
     * @description:
     */
    public class Test {
        public static void main(String[] args) {
            final MyBlockingQueue<Integer> blockingQueue = new MyBlockingQueue<Integer>(2);
            for (int i = 0; i < 5; i++) {
                final int data = i;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            blockingQueue.enqueue(data);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
            for (int i = 0; i < 5; i++) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            blockingQueue.dequeue();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        }
    }
    
    

    结果

    了解更多看这个博客,写的非常不错
    https://www.cnblogs.com/takumicx/p/9338983.html

    作者:山丘!

    -------------------------------------------

    你闻讯而来,我大喜过望,我在这等你,你又在哪呢?喜欢的话加一个“关注”呗!

    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

  • 相关阅读:
    找工过程中碰到的笔试面试题整理(1)
    windows核心编程学习笔记(五.续)堆
    windows核心编程学习笔记(二)Wait For Kernel Object(s)
    windows核心编程学习笔记(四)windows内存结构/虚拟内存/线程的堆栈
    [转]筛选法求素数
    windows核心编程学习笔记(五)内存映射文件
    windows核心编程学习笔记(八)结构化异常处理(Structured Exception Handling)
    [转]亲密接触VC6.0编译器
    windows核心编程学习笔记(三)线程池(Thread Pooling)
    windows核心编程学习笔记(七)DLL Injection and API Hooking
  • 原文地址:https://www.cnblogs.com/mengd/p/15141562.html
Copyright © 2020-2023  润新知