实现生产者与消费者的3种方式

55 阅读2分钟

何为生产者与消费者模式

生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者生产者消费者

一使用阻塞队列BlockingDeque

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
public class Test {
    public static void main(String[] args) {
        BlockingDeque<Object> queue = new LinkedBlockingDeque(10);
        Thread p1 = new Thread(new Producer(queue));
        Thread p2 = new Thread(new Producer(queue));
        p1.start();
        p2.start();
        Thread c1 = new Thread(new Consumer(queue));
        c1.start();
    }
    private static class Producer implements Runnable{
        BlockingDeque<Object> queue;
        public Producer(BlockingDeque queue){
            this.queue = queue;
        }
        @Override
        public void run() {
            Object o = new Object();
            try {
              while (true){
                  queue.put(o);
                  System.out.println("生产者开始生产");
              }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private static class Consumer implements Runnable{
        BlockingDeque<Object> queue;
        public Consumer(BlockingDeque queue){
            this.queue = queue;
        }
        @Override
        public void run() {
            try {
                while (true){
                    Object take = queue.take();
                    System.out.println("消费者消费");
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

使用newCondition

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

public class MyBlockQueueForCondition {


    public static void main(String[] args){

        MyBlockQueueForCondition queue = new MyBlockQueueForCondition();

        new Thread(()->{
            try {
                while (true){
                    queue.push(new Object());
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName()+"生产数据");
                }

            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();
        new Thread(()->{
            try {
                while (true){
                    queue.push(new Object());
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName()+"生产数据");
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();

        new Thread(()->{
            try {
               while (true){
                   queue.take();
                   Thread.sleep(500);
                   System.out.println(Thread.currentThread().getName()+"消费数据");
               }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();
        new Thread(()->{
            try {
                while (true){
                    queue.take();
                    Thread.sleep(500);
                    System.out.println(Thread.currentThread().getName()+"消费数据");
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();
    }
    private int max=10;
    ReentrantLock lock = new ReentrantLock();
    Condition empty = lock.newCondition();
    Condition full = lock.newCondition();
    private LinkedList data;


    public MyBlockQueueForCondition(){
        this.data = new LinkedList();
    }
    public void push(Object obj) throws InterruptedException {

        try {
            lock.lock();
            //当集合中的数据满了 就等待 否则 就放入数据并且通知消费者消费
            while (data.size()==max){
                full.await();
            }
            data.push(obj);
            empty.signalAll();
        }finally {
            lock.unlock();
        }
    }

    public void take() throws InterruptedException{

        try {
            lock.lock();
            while (data.size()==0){
                empty.await();
            }
            data.remove();
            full.signalAll();
        }finally {

            lock.unlock();
        }
    }
}