/*
* 多线程-消费者和生产者模式
* 在实现消费者生产者模式的时候必须要具备两个前提,一是,必须访问的是一个共享资源,二是必须要有线程锁,且锁的是同一个对象
* */

 /*资源类中定义了name(名字):用来区分消费者还是生产者
* 定义了flag标记:用来区分有没有货物(默认生产一个就要消费一个)
* 定义了count(生产的个数统计)
* set方法:用来生产商品
* out方法:用来消费商品*/
class TestSource{
private String name=null;
private boolean flag=false;
private int count=0;
/*先通过flag标记判断有没有商品,有商品则等待,没有则生产商品,唤醒所有程序,并将flag标记改变*/
public synchronized void set(String name){
//判断是否有产品,这里用while循环,避免在多个生产者同时生产时,会出现生产多个产品,却只消费一个
while(flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//生产产品并输出
this.name=name+"编号"+count++;
System.out.println("生产"+name+"++");
//改变标记
flag=true;
//唤醒所有的线程
notifyAll();
}
public synchronized void out(){
while(!flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费"+name+"---");
flag=false;
notifyAll();
}
}
class Product implements Runnable{
private TestSource ts=null;
//初始化线程里用到的资源
public Product(TestSource ts){
this.ts=ts;
}
//重写线程里run方法
public void run() {
while(true){
ts.set("生产产品");
}
}
}
class Customer implements Runnable{
private TestSource ts=null;
public Customer(TestSource ts){
this.ts=ts;
}
public void run() {
while(true){
ts.out();
}
}
}
public class test {
public static void main(String[] args) {
//初始化唯一的资源
TestSource ts=new TestSource();
//创建生产者和消费者两个对象,并传入两者共同操作的唯一资源
Customer cu=new Customer(ts);
Product pr=new Product(ts);
//将对象传入线程对象
Thread t1=new Thread(cu);
Thread t2=new Thread(pr);
Thread t3=new Thread(cu);
Thread t4=new Thread(pr);
//开启线程
t1.start();
t2.start();
t3.start();
t4.start();
}
}

/*在java1.5版本以后,用lock和unlick代替了synchronized关键字
* 用await()代替了wait()方法
* 用signal()代替了notify()
* 这里的signal可以指定唤醒莫一类的线程,而不是像notifyAll,必须全部唤醒

这里我们对上面的代码进行一定的改写*/

 class TestSource{
private String name=null;
private boolean flag=false;
private int count=0;
//定义lock,用来代替synchronized关键字
private Lock lock=new ReentrantLock();
private Condition condition_pro=lock.newCondition();
private Condition condition_con=lock.newCondition();
public void set(String name){
//对代码段进行上锁
lock.lock();
try {
while(flag){
try {
//wait();
//调用生产者控制方法
condition_pro.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name=name+"编号"+count++;
System.out.println("生产"+name+"++");
flag=true;
//notifyAll();
//唤醒消费者线程
condition_con.signal();
} finally{
//解锁,让其他进程进入访问
lock.unlock();
} }
public void out(){
lock.lock();
try{
while(!flag){
try {
//wait();
condition_con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费"+name+"---");
flag=false;
//notifyAll();
condition_pro.signal();
}finally{
lock.unlock();
} }
}

java多线程-消费者和生产者模式的更多相关文章

  1. Java多线程消费者、生产者的基本思路

    多线程主要考察的就是 线程的同步控制   生产者消费者的思路就是,当 一个线程执行时让另一个线程 挂起就行了 ThreadOne.ThreadTwo同时运行,添加一个变量在一个公共类(下边的Funct ...

  2. java并发:初探消费者和生产者模式

    消费者和生产者模式 用继承Thread方式,用wait和notifyAll方法实现. 消费者和生产者模式的特点 1. 什么时候生产:仓库没有满的时候,生产者这可以生产,消费者也可以消费,仓库满的时候停 ...

  3. Java多线程编程中Future模式的详解

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  4. Java多线程编程中Future模式的详解<转>

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  5. springcloud 实现简单的 消费者和生产者 模式(Restfule 的风格)

    一.springcloud 实现简单的 消费者和生产者 模式(Restfule 的风格) 1.实现简单的消费者和生产者 springcloud使用的http协议进行传输数据,也就是说springclo ...

  6. java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现

    java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了  wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样 ...

  7. JAVA多线程经典问题 -- 生产者 消费者

    工作2年多来一直也没有计划写自己的技术博客,最近辞职在家翻看<thingking in JAVA>,偶尔看到了生产者与消费者的一个经典的多线程同步问题.本人在工作中很少使用到多线程以及高并 ...

  8. Java多线程-并发协作(生产者消费者模型)

    对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一样,Hello World!都是最经典的例子. 实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓 ...

  9. Java多线程与并发——生产者与消费者应用案例

    多线程的开发中有一个最经典的操作案例,就是生产者-消费者,生产者不断生产产品,消费者不断取走产品. package com.vince; /** * 生产者与消费者案例 * @author Admin ...

随机推荐

  1. 或许是介绍Android Studio使用Git最详细的文章

    欢迎访问我的个人博客转发请注明出处:http://www.wensibo.top/2017/03/12/GitOnAS/ 前言 本文较长,图片很多很多,流量党慎入 使用Git已经有一段时间了,但是之前 ...

  2. 1293: [SCOI2009]生日礼物

    1293: [SCOI2009]生日礼物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1096  Solved: 584[Submit][Statu ...

  3. swift -- as / 扩展

    一.使用 可选链式 调用代替强制展开 //当声明一个属性时,将属性类型设置为可选类型: 好处: 当可选类型的属性被赋予初始值时,系统调用初始值;当可选类型属性没有赋予初始值时,系统只会调用失败;如果属 ...

  4. java+++IO流操作

    序:IO流的操作主要分为两种读和写.一方面:我们可以通过不加缓冲类字符流BufferedReader/Writer和字节流BufferedInputStream/OutputStream来进行简单的读 ...

  5. 百度api使用心得体会

    最近项目中在使用百度地图api,对于其中的一些有用的点做一些归纳整理,如有不对的地方,欢迎各位大神纠正指出. 一定要学会查找百度地图api提供的类参考网站:http://lbsyun.baidu.co ...

  6. selenium+python 自动化中界面滚动条操作方法

    虽然webdriver提供了操作浏览器的前进和后退的方法,但对于浏览器滚动条并没有提供相应的操作方法,以下使用的方法: 借助JavaScript来控制浏览器的滚动条,webdriver提供了execu ...

  7. NIO(二、Buffer)

    目录 NIO(一.概述) NIO(二.Buffer) Buffer 前文讲了NIO与IO的区别,那么这一章开始讲述NIO下核心类 - Buffer类 上一章就说过,NIO的核心包括三个部分:通道(Ch ...

  8. Entity Framework 新手入门友好实例

    起因 因为实习的原因,程序之中用到了较多的数据库操作逻辑.如果每一处数据库操作都手写的话,工作量较大且后期不易于维护,所以希望能通过 ORM 框架来解决这两个问题. 在昨天之前,对于 ORM 这个词汇 ...

  9. MyBatis解决字段名与实体类属性名不相同的冲突(四)

    一.创建表和表数据 CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no ), order_price FLOA ...

  10. FastDFS分布文件系统相关资料索引

    FastDFS是为互联网应用量身定做的一套分布式文件存储系统,非常适合用来存储用户图片.视频.文档等文件.对于互联网应用,和其他分布式文件系统相比,优势非常明显.具体情况大家可以看相关的介绍文档,包括 ...