`
kingj
  • 浏览: 421190 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

java线程生产者与消费者实例(使用List实现同步)

 
阅读更多

学习java线程的时候,看到生产者与消费者例子,有感而发。

下面是模拟汽车生产商和顾客(权当消费者可以直接从厂家买到汽车),废话不说,上代码。

package com.zx.thread.work;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * 我们模拟一个生产者和消费者购买汽车的例子
 * 
 * @author maping
 * 
 */
public class ProducerAndConsumer {
    //厂家存放汽车的车间
    private static List<Car> cars = new ArrayList<Car>();

    static void test(int producers, int consumers) {
        ExecutorService exec = Executors.newCachedThreadPool();
        for (int i = 0; i < producers; i++) {
            // 上海大众的producers个分厂分别生产了100台polo车
            exec.execute(new CarProducer("上海大众", cars, 100, i));
        }

        for (int i = 0; i < consumers; i++) {
            // 消费者张三的consumers亲戚分别买10台polo
            exec.execute(new CarConsumer("张三", cars, 10, i));
        }

        exec.shutdown();
    }

    public static void main(String[] args) throws FileNotFoundException {
        test(100, 1000);
    }
}

/**
汽车类

*/
class Car {
    private String name = "polo";

    private int id;

    private CarProducer producer;

    public Car() {
    }

    public Car(CarProducer producer, String name, int id) {
        this.producer = producer;
        this.name = name;
        this.id = id;
    }

    public String toString() {
        return this.producer.getName() + "#" + this.producer.getId() + "#"
                + this.getClass().getSimpleName() + "#" + name + "#" + id;
    }
}


/*

汽车制造厂商
*/
class CarProducer implements Runnable {
    private int count;

    private List<Car> cars;

    private String name;

    private int id;

    public CarProducer(String name, List<Car> cars, int count, int id) {
        this.name = name;
        this.cars = cars;
        this.count = count;
        this.id = id;
    }

    public void addCar(int ids) {
        System.out.println(this.name + "#" + id + ">>开始生产汽车" + ids);
        //此处同步cars,如果使用BlockingQueue,则无需同步代码
        synchronized (cars) {
            cars.add(new Car(this, name, ids));
            //车间里面有了刚刚制造好的汽车,那么就可以通知消费者来买了
            cars.notifyAll();
        }

    }

    public void run() {
        for (int i = 0; i < count; i++) {
            this.addCar(i);
        }
    }

    public String getName() {
        return name;
    }

    public int getId() {
        return id;
    }
}


/**
消费者
*/
class CarConsumer implements Runnable {
    private List<Car> cars;

    private int count;

    private String name;

    private int id;

    public CarConsumer(String name, List<Car> cars, int count, int id) {
        this.name = name;
        this.cars = cars;
        this.count = count;
        this.id = id;
    }

    public void buyCar() throws InterruptedException {
     //消费者购买汽车时,锁定汽车对象
        synchronized (cars) {
            System.out.println(name + "#" + id + ">>" + "开始选车");
            int waitTime = 10 * 1000;
          //消费者刚刚来到汽车存放的车间时,如果发现
          //车间还没有汽车,那么他只能等待,这里设置了超时时间,如果
         //超过指定时间,则一气走之,相当于抛出异常了
            while (cars.isEmpty()) {
                System.out.println("[" + name + "#" + id + "]当前车缺货,等待"
                        + waitTime + "毫秒");
                wait(waitTime);
            }
         //有汽车来了,则个时候就可以买汽车了
            Car car = cars.remove(0);
            System.out.println("[" + name + "#" + id + "]" + "买到车了" + car);
            System.out.println("***************************");
            System.err.println("当前库存为\n" + cars.size());
        }
    }

    public void run() {
        while (count-- > 0) {
            try {
                buyCar();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

 

这段代码在生产者线程制造的汽车数>=消费者线程购买的汽车数时,没有任何问题,当反之的时候,就会由于

等待制造商生产汽车,而此时制造商或许不再制造汽车了,那么就会抛出异常。

    我在思考,比如MQ的消息队列是怎么做到那么高效率呢

分享到:
评论

相关推荐

    JAVA上百实例源码以及开源项目源代码

     Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText(); //得到服务器地址  ...

    java源码包---java 源码 大量 实例

     Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText(); //得到服务器地址  ...

    java编程基础,应用与实例

    14.7.3 生产者与消费者 221 14.7.4 多消费者 224 14.8 stop()、suspend()和resume() 225 14.9 巩固练习 226 第15章 常用API之二 228 15.1 Collection接口 228 15.1.1 Set接口 228 15.1.2 List接口 ...

    JAVA上百实例源码以及开源项目

    百度云盘分享 ... Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText();...

    Java开发技术大全(500个源代码).

    producer_consumer.java 演示生产者-消费者线程 consumer.java 消费者线程 producer.java 生产者线程 common.java 公有类 第9章 示例描述:本章学习运行时类型识别。 Candy.java 一个用来测试的简单类 ...

    Java JDK实例宝典

    19 线程——BlockingQueue 第17章 Java与XML 17. 1 用DOM处理XML文档 17. 2 用SAX处理XML文档 17. 3 用XSLT转换XML 17. 4 对象与XML的转换 第18章 Java Mail 18. 1 使用SMTP协议发送...

    java初学者必看

    11.5.3 运行生产者/消费者 11.6 死锁 11.7 本章习题 第12章 异常处理 12.1 异常的概念 12.2 异常的基本样式 12.3 Java异常类 12.3.1 异常类层次结构 12.3.2 异常处理方法 12.4 异常捕获 12.4.1 异常捕获...

    java源码包4

     Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText(); //得到服务器...

    java源码包3

     Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText(); //得到服务器...

    java源码包2

     Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText(); //得到服务器...

    JAVA面试题最全集

    12.synchronized (生产者和消费) 13.String 和 StringBuffer 14.Serializable 15.MVC (Struts的工作流程) 16.什么是MDA 17.tcp与udp的区别 18.链表与散列表和数组的区别 19.堆和栈的区别 20.ejb的分类及...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    Java实现的FTP连接与数据浏览程序 1个目标文件 摘要:Java源码,网络相关,FTP Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。 部分源代码摘录: ftpClient = new FtpClient(); //实例化FtpClient对象 ...

    Java开发详解.zip

    030905_【第9章:多线程】_线程操作案例——生产者和消费者笔记.pdf 030906_【第9章:多线程】_线程生命周期笔记.pdf 031001_【第10章:泛型】_泛型入门笔记.pdf 031002_【第10章:泛型】_通配符笔记.pdf 031003_...

    Java并发编程(学习笔记).xmind

    生产者-消费者模式 中断的处理策略 传递InterruptedException 恢复中断,让更高层的代码处理 PriorityQueue(非并发) ConcurrentSkipListMap 替代同步的SortedMap ...

    Java典型模块

    7.3 实现线程通信的生产者与消费者项目 7.3.1 生产者和消费者的类 7.3.2 储存库的类 7.4 知识点扩展——线程的通信知识 7.4.1 线程通信的基本知识 7.4.2 线程通信的具体实例 7.5 小结 第8章 关机工具(Timer类+系统...

    JAVA基础课程讲义

    生产者/消费者模式 181 线程回顾总结 184 任务调度(补充内容,了解即可!) 184 思考作业 185 上机作业 185 第十章 网络编程 186 基本概念 186 什么是计算机网络 186 计算机网络的主要功能 186 什么是网络通信协议 ...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    Java实现的FTP连接与数据浏览程序 1个目标文件 摘要:Java源码,网络相关,FTP Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。 部分源代码摘录: ftpClient = new FtpClient(); //实例化FtpClient对象 ...

Global site tag (gtag.js) - Google Analytics