再谈线程:生产者与消费者

场景描述:

一个仓库,生产者在工厂里生产了产品后,将产品存放到仓库里,仓库存放数量有限,当满仓后,停 止生产,直到有消费着将产品消费后才继续生产;消费者从仓库里提取产品,当仓库空仓时,停止消费产 品,直到仓库中有产品时,才继续消费产品。

代码的实现(调整线程sleep时间可以实现生产速度与消费速度的不同):

TestProduceAndConsumer.java

package com.nantian;import java.util.Random;public class TestProduceAndConsumer {    public static void main(String[] args) {        // 创建一个工厂对象        ProductFacTory pf = new ProductFacTory();        // 创建一个生产者和一个消费者,传递工厂的引用,保证两者操作的是同一个工厂         Producer p = new Producer(pf);        Consumer c = new Consumer(pf);        // 启动两个线程        p.start();        c.start();    }}// 产品工厂class ProductFacTory {    // product表示仓库    private char[] product = { ' ', ' ', ' ', ' ', ' '};    // flag标记产品数量    private int flag = 0;    // 生产产品    public synchronized void produceProduct(char p) throws InterruptedException {        // 判断产品是否满仓,以便决定是否继续生产        if (flag == product.length) {            this.wait();        }        // 当代码执行到这里,一定不是满仓状态        product[flag++] = p;        // 查看此时仓库状态(这里不属于业务逻辑部分)        System.out.print(p + "被生产,当前仓库状态:");        for (char tmp : product) {            System.out.print(tmp);        }        System.out.println();        // 生产方法完成,如果存在等待队列中的线程,应该唤醒        this.notifyAll();    }    // 消费产品    public synchronized char consumeProduct() throws InterruptedException {        // 判断仓库是否空仓,以便决定是否消费产品        if(flag == 0) {            this.wait();        }        // 当代码执行到这里,一定不是空仓状态        char p = product[--flag]; product[flag]=' ';        // 查看此时仓库状态(这里不属于业务逻辑部分)        System.out.print(p + "被消费,当前仓库状态:");        for(char tmp : product) {            System.out.print(tmp);        }        System.out.println();        // 消费方法完成,如果存在等待队列中的线程,应该唤醒        this.notifyAll();        return p;    }}// 生产者class Producer extends Thread {    private ProductFacTory pf = null;    public Producer(ProductFacTory pf) {        this.pf = pf;    }    public void run() {        // 一共生产20个产品        for(int i=0; i<20; i++) {            // 随机产生一个大写字母作为产品            Random r = new Random();            char p = (char)(r.nextInt(26) + 'A');            try {                // 产品入库                pf.produceProduct(p);                // 故意sleep,以便消费线程有机会获得CPU时间片,方便演示                Thread.sleep(200);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}// 消费者class Consumer extends Thread {    private ProductFacTory pf = null;    public Consumer(ProductFacTory pf) {        this.pf = pf;    }    public void run() {        // 一共消费20个产品        for(int i=0; i<20; i++) {            try {                // 产品出库                pf.consumeProduct();                // 故意sleep,以便生产线程有机会获得CPU时间片,方便演示                // sleep时间稍微错开,阻止同时竞争CPU时间片                Thread.sleep(300);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

获得幸福的二法门是珍惜你所拥有的、遗忘你所没有的

再谈线程:生产者与消费者

相关文章:

你感兴趣的文章:

标签云: