生产者消费者实战
本篇主要是通过一段JAVA代码来模拟生产者和消费者的工作流程,来介绍生产者消费者这一模式。
package com.pattern; import java.util.ArrayList; import java.util.List; public class ProducerConsumerMain { /** * 缓冲区,生产者放入数据,消费者取出数据 */ private static class Buffer { /** * 存取数据通过list来实现 */ private List<Integer> data = new ArrayList<>(); /** * 设置存放最大值,当data大小达到MAX时,不允许再放数据 */ private static final int MAX = 2; /** * 设置取数的最小值,当data大小是MIN时,不允许再取数据 */ private static final int MIN = 0; public synchronized int get() { while (MIN == data.size()) { try { // 相当于this.wait();当前方法处于等待状态,并释放this对象锁,释放this监视器 wait(); } catch (InterruptedException e) { e.printStackTrace(); } } Integer i = data.remove(0); // 释放this监视器,唤醒等待this监视器的线程,但该方法不会释放this对象锁 notifyAll(); return i; } public synchronized void put(int value) { while (MAX == data.size()) { try { // 相当于this.wait();当前方法处于等待状态,并释放this对象锁,释放this监视器 wait(); } catch (InterruptedException e) { e.printStackTrace(); } } data.add(value); // 释放this监视器,唤醒等待this监视器的线程,但该方法不会释放this对象锁 notifyAll(); } } private static class Consumer extends Thread { private Buffer buffer; private int number; public Consumer(Buffer b, int number) { buffer = b; this.number = number; } @Override public void run() { int value; for (int i = 0; i < 10; i++) { // 从缓冲区中获取数据 value = buffer.get(); try { // 模拟消费数据所用时间 sleep(1000); } catch (InterruptedException e) { } System.out.println("消费者 #" + this.number + " got: " + value); } } } private static class Producer extends Thread { private Buffer buffer; private int number; public Producer(Buffer b, int number) { buffer = b; this.number = number; } @Override public void run() { for (int i = 0; i < 10; i++) { try { // 模拟生产数据所用时间 sleep(500); } catch (InterruptedException e) { } // 将数据放入缓冲区 buffer.put(i); System.out.println("生产者 #" + this.number + " put: " + i); } } } /** * 模拟生产者消费者行为 * * @param args */ public static void main(String[] args) { Buffer buffer = new Buffer(); Producer p1 = new Producer(buffer, 1); Consumer c1 = new Consumer(buffer, 1); p1.start(); c1.start(); } }