引言

生产者与消费者模型,是多线程编程中的经典问题。今天本文就来带大家手写一个生产者消费者模式

1.阻塞队列

public class CustomBlockLinkedList<E> {
    //内部使用链表实现
    private LinkedList<E> linkedList;
    //队列容量最大值
    private final int maxSize;
    //当前队列存储的对象数量
    private AtomicInteger count = new AtomicInteger(0);

    /**
     * 队列容量最大值默认10
     */
    public CustomBlockLinkedList() {
        this.linkedList = new LinkedList<>();
        this.maxSize = 10;
    }

    /**
     * @param maxSize 最大值
     */
    public CustomBlockLinkedList(int maxSize) {
        this.linkedList = new LinkedList<>();
        this.maxSize = maxSize;
    }

    /**
     * 添加生产出来的产品
     *
     * @param e
     */
    public synchronized void add(E e) {
        while (count.get() >= maxSize) {
            try {
                this.wait();
            } catch (InterruptedException interruptedException) {
                interruptedException.printStackTrace();
            }
        }
        linkedList.add(e);
        count.incrementAndGet();
        this.notifyAll();
    }


    /**
     * 取出产品
     *
     * @return 返回产品
     */
    public synchronized E take() {
        while (count.get() == 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        E e = linkedList.removeFirst();
        count.decrementAndGet();
        this.notifyAll();
        return e;
    }
}

2.生产者

class Produce implements Runnable {
    CustomBlockLinkedList<Object> customBlockLinkedList;

    public Produce(CustomBlockLinkedList<Object> customBlockLinkedList) {
        this.customBlockLinkedList = customBlockLinkedList;
    }

    @Override
    public void run() {
        while (true) {
            //每1分钟生产1个
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.customBlockLinkedList.add(new Object());
            System.out.println(Thread.currentThread().getName() + " produce a object");
        }
    }
}

3.消费者

class Consumer implements Runnable {
    CustomBlockLinkedList<Object> customBlockLinkedList;

    public Consumer(CustomBlockLinkedList<Object> customBlockLinkedList) {
        this.customBlockLinkedList = customBlockLinkedList;
    }

    @Override
    public void run() {
        while (true) {
            //每1分钟消费1个
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Object take = this.customBlockLinkedList.take();
            System.out.println(Thread.currentThread().getName() + " take a object");
        }
    }
}

测试

    public static void main(String[] args) throws InterruptedException {
        CustomBlockLinkedList<Object> objectCustomBlockLinkedList = new CustomBlockLinkedList<>(30);
        Runnable runnable1 = new Produce(objectCustomBlockLinkedList);
        Runnable runnable2 = new Consumer(objectCustomBlockLinkedList);
        for (int i = 0; i < 50; i++) {
            Thread thread = new Thread(runnable1, "produce-" + i);
            thread.start();
        }
        for (int i = 0; i < 50; i++) {
            Thread thread = new Thread(runnable2, "consumer-" + i);
            thread.start();
        }
    }

输出结果