数据结构和算法--阻塞队列:双线程

该文章展示了一个使用Java实现的双锁机制阻塞队列服务,包括offer方法(添加元素),offer方法(带超时),以及poll方法(获取并移除元素)。队列使用了AtomicInteger保证数据一致性,并通过ReentrantLock和Condition进行线程同步和唤醒操作。
摘要由CSDN通过智能技术生成
package com.zwz.ThreadQueue;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 双锁实现
 *
 * @param <E>
 */
public class BlockingQueueService2<E> implements BlockingQueue<E> {

    private E[] array = (E[]) new Object[3];
    //原子变量 保证多线程数据统一性
    private AtomicInteger size = new AtomicInteger(0);
    private int tail = 0;
    private int head = 0;
    private ReentrantLock tailLock = new ReentrantLock();
    private ReentrantLock headLock = new ReentrantLock();
    private Condition tailWail = tailLock.newCondition();
    private Condition headWail = headLock.newCondition();


    @Override
    public void offer(E e) throws Exception {
        int c;
        tailLock.lockInterruptibly();
        try {
            while (isFull()) {
                tailWail.await();
            }
            array[tail] = e;
            c = size.getAndIncrement();
            //自我唤醒 线程中还有空位
            if(c < array.length - 1){
                tailWail.signal();
            }
        } finally {
            tailLock.unlock();
        }
        
    }

    @Override
    public Boolean offer(E e, Long timeout) throws Exception {
        int c;
        tailLock.lockInterruptibly();
        try {
            //使用超时时间处理
            Boolean flag = true;
            while (isFull()) {
                if (!flag) {
                    return false;
                }
                flag = tailWail.await(timeout, TimeUnit.SECONDS);
            }
            array[tail] = e;
            c = size.getAndIncrement();
            //自我唤醒 线程中还有空位
            if(c < array.length - 1){
                tailWail.signal();
            }
        } finally {
            tailLock.unlock();
        }
        
        //唤醒读取线程,线程不为空的清空
        if(c == 0){
            headLock.unlock();
            try {
                headWail.signal();
            } finally {
                headLock.unlock();
            }
        }
        return true;
    }

    @Override
    public E poll() throws Exception {
        int c;
        E e = null;
        headLock.lockInterruptibly();
        try {
            while (isEmpty()) {
                headWail.await();
            }
            e = array[head];
            array[head] = null;
            head++;
            c = size.getAndDecrement();
            //线程不为空时,自我唤醒
            if(c > 1){
                headWail.signal();
            }
        } finally {
            headLock.unlock();
        }
        //线程不满时,唤醒插入线程
        if(c == array.length){
            tailLock.unlock();
            try {
                tailWail.signal();
            } finally {
                tailLock.unlock();
            }
        }
        return e;
    }

    private Boolean isEmpty() {
        return size.get() == 0;
    }

    private Boolean isFull() {
        return size.get() == array.length;
    }

    @Override
    public List<E> getList() {
        List<E> list = new ArrayList<>();
        for (E e : array) {
            list.add(e);
        }
        return list;
    }


    public static void main(String[] args) {
        BlockingQueue<Integer> queue = new BlockingQueueService2<>();
        LocalDateTime now = LocalDateTime.now();
        new Thread(() -> {
            try {

                System.out.println(now);
                queue.offer(1);
                System.out.println(queue.getList());
                queue.offer(2);
                System.out.println(queue.getList());
                queue.offer(3);
                System.out.println(queue.getList());

                queue.offer(4, 5L);
                System.out.println(queue.getList());

                System.out.println("终止:" + Duration.between(now, LocalDateTime.now()).getSeconds());
            } catch (Exception e) {

            }
        }, "this").start();

        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
                System.out.println(queue.poll());
                System.out.println(queue.getList());
                System.out.println("读取:" + Duration.between(now, LocalDateTime.now()).getSeconds());

                //queue.offer(6);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }).start();

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值