Java并发编程七 生产者消费者模式

Java并发编程七 生产者消费者模式

生产者-消费者模式是一个经典的多线程设计模式,它为多线程的协作提供了良好的解决方案。在生产者-消费者模式中,通常有两类线程,即若干个生产者线程和若干个消费者线程。生产者线程负责提交用户请求,消费者线程负责处理用户请求。生产者和消费者之间通过共享内存缓冲区进行通信。
生产者-消费者模式中的内存缓冲区的主要功能是数据在多线程间的共享。此外,通过该缓冲区,可以缓解生产者和消费者之间的性能差。
生产者消费者模式

阻塞队列实现

举一个鸡下蛋供人吃的例子:

/**
 * 鸡蛋
 * Created by lyyz on 18-5-15.
 */
public class Egg {
    private String id;

    public Egg(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}
/**
 * 生产者 鸡下蛋装入篮子
 * Created by lyyz on 18-5-15.
 */
public class Chicken implements Runnable {
    private String name;
    private BlockingQueue<Egg> queue;
    private AtomicInteger count = new AtomicInteger();
    private volatile boolean isRunning = true;
    public Chicken(String name, BlockingQueue<Egg> queue) {
        this.name = name;
        this.queue = queue;
    }

    @Override
    public void run() {
        while(isRunning){
            try {
                Thread.sleep(new Random().nextInt(1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count.incrementAndGet();
            Egg egg = new Egg("鸡-"+name+"-"+count.get());
            queue.add(egg);
            System.out.println("鸡-"+name+"下了第"+count.get()+"个蛋 放入篮子中");
        }
    }

    public void stop(){
        isRunning = false;
    }
}

/**
 * 消费者 人吃篮子中的鸡蛋
 * Created by lyyz on 18-5-15.
 */
public class People implements Runnable {
    private String name;
    private BlockingQueue<Egg> queue;
    private AtomicInteger count = new AtomicInteger();
    private volatile boolean isRunning = true;
    public People(String name, BlockingQueue<Egg> queue) {
        this.name = name;
        this.queue = queue;
    }

    @Override
    public void run() {
        while(isRunning){
            try {
                Thread.sleep(new Random().nextInt(1000));
                count.incrementAndGet();
                Egg egg = queue.take();
                System.out.println("人-"+name+"吃了 "+egg.getId()+"这是吃的第"+count.get()+"个蛋了");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void stop(){
        isRunning = false;
    }
}
/**
 * 鸡下蛋供人吃的例子
 * Created by lyyz on 18-5-15.
 */
public class Main {
    public static void main(String[] args) {
        //阻塞的有界队列 装鸡蛋的篮子
        BlockingQueue<Egg> queue = new ArrayBlockingQueue<Egg>(10);
        //创建4只鸡
        Chicken chicken1 = new Chicken("小红",queue);
        Chicken chicken2 = new Chicken("小黄",queue);
        Chicken chicken3 = new Chicken("小黑",queue);
        Chicken chicken4 = new Chicken("小绿",queue);
        //创建三个人
        People people1 = new People("刘备",queue);
        People people2 = new People("张飞",queue);
        People people3 = new People("关羽",queue);
        //线程池
        ExecutorService es = Executors.newCachedThreadPool();
        es.execute(chicken1);
        es.execute(chicken2);
        es.execute(chicken3);
        es.execute(chicken4);
        es.execute(people1);
        es.execute(people2);
        es.execute(people3);

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        chicken1.stop();
        chicken2.stop();
        chicken3.stop();
        chicken4.stop();
        while(!queue.isEmpty()){

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        people1.stop();
        people2.stop();
        people3.stop();
        es.shutdown();
        System.out.println("--------------------end------------------------");
    }
}

猜你喜欢

转载自blog.csdn.net/oyueyang1/article/details/80324171