Java 多线程编程 通过 ReentrantLock锁, 实现阻塞队列

Java 多线程编程 通过 ReentrantLock锁, 实现阻塞队列

1. 自定义简单阻塞队列实现类


import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class CustomBlockingQueue<T> {
    /** 队列长度*/
    private final int size;

    /** 链表用于保存数据*/
    private final LinkedList<T> list = new LinkedList<>();

    /** 重入锁*/
    private final Lock lock = new ReentrantLock();

    /** 队列满时的等待条件*/
    private final Condition notFull = lock.newCondition();

    /** 队列空时的等待条件*/
    private final Condition notEmpty = lock.newCondition();

    public CustomBlockingQueue(final int size) {
        this.size = size;
    }

    /**
     * 如果队列满, 则阻塞
     * */
    public void add(T value) throws InterruptedException {
        lock.lock();
        try {
            while(list.size() == size) {
                System.out.println("队列已满 -- 入队过程进入等待");
                notFull.await();
            }
            /** 入队到链表末尾*/
            list.add(value);
            /** 唤醒在 notEmpty条件内等待的线程*/
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 如果队列为空, 则阻塞
     * */
    public T take() throws InterruptedException {
        T value;
        lock.lock();
        try {
            while(list.size() == 0) {
                System.out.println("队列为空 -- 出队过程进入等待");
                notEmpty.await();
            }
            /** 移除并返回链表头部的元素*/
            value = list.removeFirst();
            /** 唤醒在 notFull条件内等待的线程*/
            notFull.signal();
        } finally {
            lock.unlock();
        }

        return value;
    }

}

2. App.java


public class App {
    public static void main(String[] args) {
        final CustomBlockingQueue<Integer> queue = new CustomBlockingQueue<>(3);

        /** 多线程入队*/
        new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                System.out.println("入队: " + i);
                try {
                    queue.add(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        /** 多线程出队*/
        new Thread(() -> {
            for(int i = 0; i < 100; i++) {
                try {
                    System.out.println("出队: " + queue.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

}

如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!

发布了62 篇原创文章 · 获赞 325 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qcl108/article/details/101944750