手写一个有界阻塞队列 ✨每日积累

简介: 手写一个有界阻塞队列 ✨每日积累
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestBoundedQueue {
    public static void main(String[] args) throws Exception {
        BoundedQueue<String> stringTestBoundedQueue = new BoundedQueue<>(16);
        FutureTask<String> callableFutureTask = new FutureTask<>(new Callable<String>() {
            @Override
            public String call() throws Exception {
                Thread.sleep(100);
                String removeStr = stringTestBoundedQueue.remove();
                System.out.println("移除满队列的一个元素:" + removeStr);
                return removeStr;
            }
        });
        new Thread(callableFutureTask).start();
        for (int i = 0; i <= 16; i++) {
            System.out.println(i);
            stringTestBoundedQueue.add(i + "");
        }
        System.out.println("--------主程序结束---------");
    }
}
class BoundedQueue<T> {
    //装载元素数组
    private Object[] items;
    //添加的下标,删除的下标和数组当前数量
    private int addIndex, removeIndex, count;
    private Lock lock = new ReentrantLock();
    private Condition notEmpty = lock.newCondition();
    private Condition notFull = lock.newCondition();
    public BoundedQueue(int initQueueSize){
        items = new Object[initQueueSize];
    }
    /**
     *  添加元素,如果数组队列已满,调用添加的线程进入等待状态,直到有空余位置
     * @param t 所要添加元素
     * @throws Exception
     */
    public void add(T t) throws Exception{
        lock.lock();
        try {
            while (count == items.length) {
                //插入时已经满了则添加线程进入等待状态
                System.out.println("队列已满,阻塞调用add()线程。");
                notFull.await();
            }
            items[addIndex] = t;
            addIndex++;
            if (addIndex == items.length)
                addIndex = 0;
            count++;
            notEmpty.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    /**
     * 数组为空时,调用删除的线程进入等待状态,只有有新元素供其返回使用
     * @return 返回一个头元素
     * @throws Exception
     */
    public T remove() throws Exception{
        Object removeElement = null;
        lock.lock();
        try {
            while (count == 0) {
                System.out.println("队列为空,阻塞调用remove()线程");
                notEmpty.await();
            }
            removeElement = items[removeIndex];
            removeIndex++;
            if (removeIndex == items.length)
                removeIndex = 0;
            count--;
            notFull.signal();
            return (T)removeElement;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
        return (T)removeElement;
    }
}

运行结果

1.png

相关文章
|
2月前
|
机器学习/深度学习 算法 云计算
探索无界:我的技术之旅与感悟####
【10月更文挑战第29天】 在技术的浩瀚星海里,我如同一名初出茅庐的航海家,驾驶着名为“好奇心”的小舟,穿梭于知识的岛屿之间。本文不仅是一次技术的探索之旅,更是一场心灵的洗礼。从最初的迷茫与困惑,到后来的顿悟与成长,每一步都凝聚着汗水与智慧的结晶。这不仅仅是一篇关于技术的文章,它还是个人成长、自我超越的见证。在这里,我将分享几个关键技术领域的深入探索,以及这些经历如何塑造了我的技术哲学和人生观。 ####
34 2
|
7月前
|
存储 Java 索引
告别Java集合小白!一文读懂List的精髓
【6月更文挑战第17天】Java中的List接口作为有序集合,允许存储和操作有序元素,支持重复值。ArrayList和LinkedList是常见实现类:ArrayList基于数组,适合快速访问但插入删除慢;LinkedList基于链表,插入删除快但访问慢。了解其核心概念、方法及泛型使用,能提升编程效率和代码质量。示例代码展示了添加和访问元素。通过深入学习,可以更好地掌握List的高级用法。
72 1
|
8月前
|
程序员 开发工具 Python
最全学Python有什么用?看完这些你肯定明白_学pysion的作用,2024年最新字节跳动面试严格吗
最全学Python有什么用?看完这些你肯定明白_学pysion的作用,2024年最新字节跳动面试严格吗
最全学Python有什么用?看完这些你肯定明白_学pysion的作用,2024年最新字节跳动面试严格吗
|
8月前
|
前端开发 算法 JavaScript
快来get策略模式,告别编程困惑,轻松变身编程高手✨
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。
|
8月前
|
监控 Java 数据库连接
年薪百万的offer从何入手?剑指P8的《Spring 5高级编程》PDF
如果想要解释Spring,那么最难的部分就是对其进行分类。通常情况下,Spring 被描述为构建Java应用程序的轻量级框架,但这种描述带来了两个有趣的观点。
年薪百万的offer从何入手?剑指P8的《Spring 5高级编程》PDF
|
8月前
|
Java
剑指JUC原理-12.手写简易版线程池思路
剑指JUC原理-12.手写简易版线程池思路
46 0
|
Cloud Native Linux Go
开源项目在面试中的作用:如何用你的贡献加分
开源项目在面试中的作用:如何用你的贡献加分
124 0
|
缓存 Java 程序员
肝到头秃!百度强推并发编程笔记我爱了,原来这才叫并发
随着Java程序员的大幅增长,人们对Java程序员的要求也是越来越严苛。从现在Java岗的招聘需求来看,并发编程已经是我们Java程序员避不开的坎了! 编写正确的程序并不容易,而编写正确的并发程序就更难了。与顺序执行的程序相比,并发程序中显然更容易出现错误。而且并发性错误通常并不会以某种确定的方式显现出来。
面试官:小伙子我们先来唠唠并发编程的几大核心知识点
并发编程算是Java的一个难点,经常做业务相关的程序员基本上用不到juc的包,但是这些知识点十分重要,所以不管在哪里,时刻保持学习真的很重要。
JUC之FutureTask源码深度剖析 ✨ 每日积累
JUC之FutureTask源码深度剖析 ✨ 每日积累
JUC之FutureTask源码深度剖析 ✨ 每日积累

相关实验场景

更多