本文来自:http://www.cnblogs.com/happyPawpaw/archive/2013/01/18/2865957.html

引言

  生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况:

  存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间中添加产品。互相等待,从而发生死锁。

JAVA解决线程模型的三种方式

  1、wait()和notify()

import java.util.LinkedList;

public class ProducerConsumer {
    private LinkedList<Object> storeHouse = new LinkedList<Object>();
    private int MAX = 10;

    public ProducerConsumer() {
    }

    public void start() {
        new Producer().start();
        new Comsumer().start();
    }

    class Producer extends Thread {
        public void run() {
            while (true) {
                synchronized (storeHouse) {
                    try {
                        while (storeHouse.size() == MAX) {
                            System.out.println("storeHouse is full , please wait");
                            storeHouse.wait();
                        }
                        Object newOb = new Object();
                        if (storeHouse.add(newOb)) {
                            System.out.println("Producer put a Object to storeHouse");
                            Thread.sleep((long) (Math.random() * 3000));
                            storeHouse.notify();
                        }
                    } catch (InterruptedException ie) {
                        System.out.println("producer is interrupted!");
                    }

                }
            }
        }
    }

    class Comsumer extends Thread {
        public void run() {
            while (true) {
                synchronized (storeHouse) {
                    try {
                        while (storeHouse.size() == 0) {
                            System.out.println("storeHouse is empty , please wait");
                            storeHouse.wait();
                        }
                        storeHouse.removeLast();
                        System.out.println("Comsumer get  a Object from storeHouse");
                        Thread.sleep((long) (Math.random() * 3000));
                        storeHouse.notify();
                    } catch (InterruptedException ie) {
                        System.out.println("Consumer is interrupted");
                    }

                }
            }

        }
    }

    public static void main(String[] args) throws Exception {
        ProducerConsumer pc = new ProducerConsumer();
        pc.start();
    }
}

  2、await()和signal(),即线程锁的方式

package sort;

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

public class ProducerConsumer {
    private LinkedList<Object> myList = new LinkedList<Object>();
    private int MAX = 10;
    private final Lock lock = new ReentrantLock();
    private final Condition full = lock.newCondition();
    private final Condition empty = lock.newCondition();

    public ProducerConsumer() {
    }

    public void start() {
        new Producer().start();
        new Consumer().start();
    }

    public static void main(String[] args) throws Exception {
        ProducerConsumer s2 = new ProducerConsumer();
        s2.start();
    }

    class Producer extends Thread {
        public void run() {
            while (true) {
                lock.lock();
                try {
                    while (myList.size() == MAX) {
                        System.out.println("warning: it's full!");
                        full.await();
                    }
                    Object o = new Object();
                    if (myList.add(o)) {
                        System.out.println("Producer: " + o);
                        empty.signal();
                    }
                } catch (InterruptedException ie) {
                    System.out.println("producer is interrupted!");
                } finally {
                    lock.unlock();
                }
            }
        }
    }

    class Consumer extends Thread {
        public void run() {
            while (true) {
                lock.lock();
                try {
                    while (myList.size() == 0) {
                        System.out.println("warning: it's empty!");
                        empty.await();
                    }
                    Object o = myList.removeLast();
                    System.out.println("Consumer: " + o);
                    full.signal();
                } catch (InterruptedException ie) {
                    System.out.println("consumer is interrupted!");
                } finally {
                    lock.unlock();
                }
            }
        }
    }

}

  3、阻塞队列的方式

import java.util.concurrent.*;

public class ProducerConsumer {
    // 建立一个阻塞队列
    private LinkedBlockingQueue<Object> queue = new LinkedBlockingQueue<Object>(10);

    public ProducerConsumer() {
    }

    public void start() {
        new Producer().start();
        new Consumer().start();
    }

    public static void main(String[] args) throws Exception {
        ProducerConsumer s3 = new ProducerConsumer();
        s3.start();
    }

    class Producer extends Thread {
        public void run() {
            while (true) {
                try {
                    Object o = new Object();
                    // 取出一个对象
                    queue.put(o);
                    System.out.println("Producer: " + o);
                } catch (InterruptedException e) {
                    System.out.println("producer is interrupted!");
                }
                // }
            }
        }
    }

    class Consumer extends Thread {
        public void run() {
            while (true) {
                try {
                    // 取出一个对象
                    Object o = queue.take();
                    System.out.println("Consumer: " + o);
                } catch (InterruptedException e) {
                    System.out.println("producer is interrupted!");
                }
                // }
            }
        }
    }

}

结论

三种方式原理一致,都是对独占空间加锁,阻塞和唤醒线程,第一种方式比较传统,第三种方式最简单,只需存储和取用,线程同步的操作交由LinkedBlockingQueue全权处理。

java简单模拟生产者消费者问题的更多相关文章

  1. java多线程模拟生产者消费者问题,公司面试常常问的题。。。

    package com.cn.test3; //java多线程模拟生产者消费者问题 //ProducerConsumer是主类,Producer生产者,Consumer消费者,Product产品 // ...

  2. 使用.NetCore自带的后台作业,出入队简单模拟生产者消费者处理请求响应的数据

    环境:Core:3.1的项目 说明:由于该方案为个人测试项目,重启时队列中的部分数据很可能会丢失, 对数据有要求的该方案不适用,不能照搬需要持久化处理, 另外发布到Linux Docker中通常不会自 ...

  3. Java设计模式之生产者消费者模式

    Java设计模式之生产者消费者模式 博客分类: 设计模式 设计模式Java多线程编程thread 转载 对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一 ...

  4. 第23章 java线程通信——生产者/消费者模型案例

    第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...

  5. java多线程解决生产者消费者问题

    import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class ...

  6. java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-【费元星Q9715234】

    java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-[费元星Q9715234] 说明如下,不懂的问题直接我[费元星Q9715234] 1.反射的意义在于不将xml tag ...

  7. Python-生成器实现简单的"生产者消费者"模型

    一.使用生成器实现简单的生产者消费者模型, 1.效果截屏 代码如下: import time def consumer(name): print('%s 开始买手机' %name) while Tru ...

  8. JAVA多线程之生产者 消费者模式 妈妈做面包案例

    创建四个类 1.面包类 锅里只可以放10个面包 ---装面包的容器2.厨房 kitchen 生产面包 和消费面包  最多生产100个面包3.生产者4消费者5.测试类 多线程经典案例 import ja ...

  9. Java里的生产者-消费者模型(Producer and Consumer Pattern in Java)

    生产者-消费者模型是多线程问题里面的经典问题,也是面试的常见问题.有如下几个常见的实现方法: 1. wait()/notify() 2. lock & condition 3. Blockin ...

随机推荐

  1. PHP开发环境的配置

    PHP的开发环境主要包括:安装和配置Apache服务器.PHP引擎以及MySQL数据库服务器,另外选用Dreamweaver作为PHP的开发工具. 1.安装和测试Apache 首先下载Apache:官 ...

  2. Java 特定规则排序-LeetCode 179 Largest Number

    Given a list of non negative integers, arrange them such that they form the largest number. For exam ...

  3. 【分布式】Zookeeper客户端

    一.前言 前篇博客分析了Zookeeper的序列化和通信协议,接着继续学习客户端,客户端是开发人员使用Zookeeper最主要的途径,很有必要弄懂客户端是如何与服务端通信的. 二.客户端 2.1 客户 ...

  4. 把PDF的底色改成护眼色,这样读起文章来就不是很累了······

    PDF格式背景改变方法如下: 打开PDF 点击 编辑 ->首选项->辅助工具->选中"替换文档颜色"和" 自定义颜色"->将背景颜色改成 ...

  5. Kafka0.8.2.1删除topic逻辑

    前提条件: 在启动broker时候开启删除topic的开关,即在server.properties中添加:  delete.topic.enable=true 命令: bin/kafka-topics ...

  6. 基于Metronic的Bootstrap开发框架经验总结(13)--页面链接收藏夹功能的实现2(利用Sortable进行拖动排序)

    在上篇随笔<基于Metronic的Bootstrap开发框架经验总结(12)--页面链接收藏夹功能的实现>上,我介绍了链接收藏夹功能的实现,以及对收藏记录的排序处理.该篇随笔主要使用功能按 ...

  7. Date.parse

    JavaScript: Date.parse(),一个参数,参数类型是 JavaScript 中的 Date 类型. 返回值 : 得到一个 Unix 时间戳,比如说,1470993235000,这种东 ...

  8. nginx+lua

    一场电闪与雷鸣的结合, 公司原有服务器已经配置好nginx,需要重新装载lua模块,哈哈哈,无法无法.   安装LUA模块需要以下 pcre       ftp://ftp.csx.cam.ac.uk ...

  9. 开源跨平台IOT通讯框架ServerSuperIO,集成到NuGet程序包管理器,以及Demo使用说明

          物联网涉及到各种设备.各种传感器.各种数据源.各种协议,并且很难统一,那么就要有一个结构性的框架解决这些问题.SSIO就是根据时代发展的阶段和现实实际情况的结合产物. 各种数据信息,如下图 ...

  10. spider RPC安全性

    spider提供了多重安全保障机制,目前主要支持接入握手校验,报文完整性校验,报文加密,报文长度检查四种机制. 接入认证 spider使用两次握手校验,其握手流程如下: 签名AES加密的方式实现. l ...