动手实现阻塞队列

本文介绍了如何动手实现一个简单的Java阻塞队列。内容涵盖阻塞队列的基本属性,如数据存储、索引管理、队列大小等,并详细阐述了入队和出队的方法,包括在满队列时阻塞入队线程,空队列时阻塞出队线程的机制。通过这样的设计,实现了线程间的同步和数据交换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    使用等待通知模式实现阻塞队列

一、阻塞队列的属性

    1、一个存储数据的数组

    2、添加元素的索引,相当于队尾

    3、取出元素的索引,相当于队头

    3、队列中的元素个数

    4、一个互斥锁

    5、一个监视队列为空的监视器,一个监视队列为满的监视器

//存储数据的数组
private Object[] data;
//添加下标和删除下标和数组当前数量
private int addIndex,removeIndex,size;
private Lock lock = new ReentrantLock();
//监视数组是否为空
private Condition notEmpty  = lock.newCondition();
//监视数组是否为满
private Condition notFull  = lock.newCondition();

二、构造方法

    为了简单,我只写了一个传入初始容量的构造方法

public BlockArray(int capa){
    data = new Object[capa];
}

三、入队方法

    在入队时进行加锁,然后判断队列是否满了,如果满了,阻塞当前线程,不然元素入队,因为这是有界队列,所以在添加后判断队列是否已满,如果已满,则将入队索引置0,size加1,唤醒出队的线程。

public void add(T x) throws InterruptedException {
    lock.lock();
    try {
        while (size == data.length)
            notFull.await();
        data[addIndex++] = x;
        if (addIndex == data.length)
            addIndex = 0;
        size++;
        notEmpty.signal();
    }finally {
        lock.unlock();
    }
}

四、出队方法

    在出队时进行加锁,然后判断队列是否为空,如果为空,则阻塞线程,不然出队头,判断出队索引是否越界,如果越界,将其置0,队列元素个数减1,唤醒入队线程。返回队头元素值。

public T remove() throws InterruptedException {
    lock.lock();
    try {
        while (size == 0)
            notEmpty.await();
        Object x = data[removeIndex];
        data[removeIndex++] = null;
        if (removeIndex == data.length)
            removeIndex = 0;
        size--;
        notFull.signal();
        return (T)x;
    }finally {
        lock.unlock();
    }
}

    这样一个简单的阻塞队列就已经完成了。源代码如下

class BlockArray<T>{
    @Override
    public String toString() {
        return "BlockArray{" +
                "data=" + Arrays.toString(data) +
                '}';
    }

    //存储数据的数组
    private Object[] data;
    //添加下标和删除下标和数组当前数量
    private int addIndex,removeIndex,size;
    private Lock lock = new ReentrantLock();
    //监视数组是否为空
    private Condition notEmpty  = lock.newCondition();
    //监视数组是否为满
    private Condition notFull  = lock.newCondition();

    public BlockArray(int capa){
        data = new Object[capa];
    }

    public void add(T x) throws InterruptedException {
        lock.lock();
        try {
            while (size == data.length)
                notFull.await();
            data[addIndex++] = x;
            if (addIndex == data.length)
                addIndex = 0;
            size++;
            notEmpty.signal();
        }finally {
            lock.unlock();
        }
    }

    public T remove() throws InterruptedException {
        lock.lock();
        try {
            while (size == 0)
                notEmpty.await();
            Object x = data[removeIndex];
            data[removeIndex++] = null;
            if (removeIndex == data.length)
                removeIndex = 0;
            size--;
            notFull.signal();
            return (T)x;
        }finally {
            lock.unlock();
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值