在实现生产者消费者模式之前,我们先了解一下线程的5种状态:被创建、运行、冻结、消亡、阻塞,如下图:
在Jdk1.5发布之前,我们实现生产者消费者模式一般使用synchronized + while循环实现。
下面就这一方法,围绕一个小需求,进行代码实现:
package com.shindo.java.thread; /** * 需求:生产者生产一个商品,消费者消费一个商品 */ public class ProducerAndConsumerPattern { public static void main(String[] args){ Resource r = new Resource(); //定义两个线程同时运行:一个负责生产商品,一个负责消费商品 new Thread(new Producer(r)).start(); new Thread(new Consumer(r)).start(); } } /** * 定义资源 */ class Resource{ //定义需要打印的商品名称 private String name; //定义自增长变量 private int count = 1; //定义逻辑判断标签 private boolean flag = false; public synchronized void set(String name){ //若flag标志位为true,当前线程进入冻结状态 while(flag) try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } //打印当前生产的商品名字 this.name = name + "--" + count++; System.out.println(Thread.currentThread().getName()+"--生产者--"+this.name); //生产商品后,改变标志位,为消费者做准备 flag = true; //唤醒冻结线程:改方法会唤醒包括己方、对方线程在内的所有线程 this.notifyAll(); } public synchronized void out(){ //当flag标志位为false时,当前线程进入冻结状态 while(!flag) try { this.wait(); } catch (Exception e) { e.printStackTrace(); } //打印当前消费的商品 System.out.println(Thread.currentThread().getName()+"--&&消费者&&--"+ this.name); //消费商品后,改变标志位状态,为生产者做准备 flag = false; //唤醒所有冻结线程 this.notifyAll(); } } /** * 定义生产者 */ class Producer implements Runnable{ private Resource res; Producer(Resource res){ this.res = res; } public void run(){ while(true){ res.set("*商品*"); } } } /** * 定义消费者 */ class Consumer implements Runnable{ private Resource res; Consumer(Resource res){ this.res = res; } public void run(){ while(true){ res.out(); } } }
代码运行效果如下,实现了一个线程负责生产商品,另一个线程负责消费商品: