线程通信示例——生产者消费者问题

这类问题描述了一种情况,假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中的产品取走消费.假设仓库中没有产品,则生产者可以将 产品放入仓库,有产品,则停止生产并等待,直到仓库中的产品被消费这取走为止. 如果仓库中放油产品,则消费者可以将产品取走消费,否则停止消费并等待,直到 仓库中再次放入产品为止. 显然,这是一个同步问题,生产者和消费这共享同一资源, 并且生产者和消费这之间彼此依赖,互为条件向前推进.Java提供了3个方法解决了线程间的通信问题,分别是wait() notify() 和 notifyAll()
* (1)调用wait()方法: 使调用该方法的线程释放共享资源的锁,然后从运行状态退出, 进入等待队列,直到被再次唤醒
* (2)调用notify()方法: 唤醒等待队列中第一个等待同一共享资源的线程,并使该线程退出等待,进入就绪状态
* (3)调用notifyAll()方法: 使所有正在等待队列中同一共享资源的线程从等待状态退出,此时优先级最高的那个线程最先执行

/* wait()方法使调用该方法的线程释放共享资源的锁,然后从运行状态退出, 进入等待队列,直到被再次唤醒 */

 package com.iotek.productconsumerdemo;

 import java.util.LinkedList;

 public class ProductorConsumerDemo {

     /**
* 线程通信-wait() notify() notifyAll()
* 在现实应用中,很多时候需要让那个多个线程按照i定的次序来访问共享资源,例如经典的生产者消费者问题:
* 这类问题描述了这样一种情况,假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者
* 将仓库中的产品取走消费,如果仓库中没有产品,在生产者可以将产品放入仓库,否则停止生产并等待,直到
* 仓库中的产品被消费这取完为止,如果仓库中放有产品,则消费者可以将产品取走消费,否则停止消费并等待,
* 直到仓库中再次放入产品为止
* @param args
*
*/
public static void main(String[] args) {
Basket basket = new Basket();
Productor productor = new Productor(basket);//创建生产者对象
Consumer consumer = new Consumer(basket);//创建消费者对象
productor.start(); //生产者启动生产
consumer.start(); //消费者开始消费
} } class Consumer extends Thread {
private Basket basket = null; public Consumer(Basket basket) {
this.basket = basket;
}
@Override
public void run() {
basket.popApple(); //消费者从篮子里取苹果
}
} class Productor extends Thread {
private Basket basket = null; public Productor(Basket basket) {
this.basket = basket;
} @Override
public void run() {
basket.pushApple(); // 生产者向篮子里放苹果
}
} // 篮子类,用来存放苹果(需要一个容器来存放,频繁存取,用LinkedList),或者取苹果
class Basket {
private LinkedList<Apple> basket = new LinkedList<Apple>(); // 放四轮苹果
public synchronized void pushApple() {
// synchronized 加锁,放苹果的时候不能取苹果
for (int i = 0; i < 20; i++) {
Apple apple = new Apple(i);
push(apple);
}
} // 取4轮苹果
public synchronized void popApple() {
for (int i = 0; i < 20; i++) {
pop();
}
} // 向篮子里面放苹果 这个方法不对外使用,因此设置为private私有的
/* public */private void push(Apple apple) {
// 如果篮子里已经有5个苹果了,就等待并通知消费者来消费
if (basket.size() == 5) {
try {
wait();// 等待,并释放当前对象的锁
/* 注意!!!调用wait()方法进入等待的线程,必须要通过其他线程调用notify()或notifyAll()方法来唤醒 */
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 如果没满5个苹果,那么就继续放苹果
try {
Thread.sleep(500);// 每隔500ms放一个苹果
// sleep()使当前线程每隔设定的休眠时间后,就自动启动线程
} catch (InterruptedException e) {
e.printStackTrace();
}
basket.addFirst(apple);// 存放苹果
System.out.println("存放:" + apple.toString());
notify();// 通知消费者来消费
} // 从篮子中取苹果
/* public */private void pop() {
// 当篮子中苹果数为0 的时候就等待并通知生产者来生产
if (basket.size() == 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 如果篮子中苹果不为0,那么就消费,每隔一定间隔,消费一个苹果
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Apple apple = basket.removeFirst();// 取出一个苹果
System.out.println("吃掉:" + apple.toString());
notify(); // 通知生产者来生产:notify()方法唤醒等待队列中第一个等待同一共享资源的线程,并使该线程进入就绪状态 }
} // 苹果类
class Apple {
private int id; public Apple(int id) {
this.id = id;
} @Override
public String toString() {
return "苹果:" + (id + 1);
}
}

Java线程通信-生产者消费者问题的更多相关文章

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

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

  2. Java多线程-同步:synchronized 和线程通信:生产者消费者模式

    大家伙周末愉快,小乐又来给大家献上技术大餐.上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式. 一.同 ...

  3. .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法

    1.多线程简单使用(1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程(2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线 ...

  4. java线程之生产者消费者

    看了毕向东老师的生产者消费者,就照着视频参考运行了一下,感觉还好 这个值得学习的是条理特别清晰: ProducterConsumerDemo.java中,一个资源类Resources,生产者消费者都可 ...

  5. Java 线程池 +生产者消费者+MySQL读取300 万条数据

    1.1需求 数据库300 万条用户数据 ,遍历获取所有用户, 各种组合关联, 获取到一个新的json ,存到redis 上. 1.2 难点 数据库比较多, 不可能单线程查询所有的数据到内存. 1.3解 ...

  6. Java如何使用线程解决生产者消费者问题?

    在Java编程中,如何使用线程解决生产者消费者问题? 以下示例演示如何使用线程解决生产者消费者问题. package com.yiibai; public class ProducerConsumer ...

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

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

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

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

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

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

随机推荐

  1. MYSQL之union和order by分析([Err] 1221 - Incorrect usage of UNION and ORDER BY)

    我在一个业务中采用了按月的分表策略,当查询的条件跨月的时候,使用了union all汇总2个表的数据,并按插入时间倒序排列.查询并不复杂,但是当执行的时候却报错了. SELECT * FROM `ta ...

  2. 138、Tensorflow serving 实现模型的部署

    将Tensorflow模型部署成Restful接口 下面是实现过程,整个操作都是在Linux上面实现的,因为Tensorflow Serving 目前还只支持Linux 这个意义真的是革命性的,因为从 ...

  3. 在windows上使用xdmcp登陆centos,红帽linux

    使用xdmcp协议可以方便的在远端登陆linux服务器,进行一些界面的操作. 修改服务器端配置. vi /etc/gdm/custom.conf 找到下面两个标签 [security] AllowRe ...

  4. 简单谈谈Netty的高性能之道

    传统RPC 调用性能差的三宗罪 网络传输方式问题:传统的RPC 框架或者基于RMI 等方式的远程服务(过程)调用采用了同步阻塞IO,当客户端的并发压力或者网络时延增大之后,同步阻塞IO 会由于频繁的w ...

  5. [HDU5807] [BestCoder Round #86 1004] Keep In Touch (DP)

    [HDU5807] [BestCoder Round #86 1004] Keep In Touch (DP) 题面 有三个人从一张N个点无重边的有向无环图上的三个点出发,每单位时间,他们分别选择当前 ...

  6. 远程连接SuSE系统的配置方法

    今天,在VMware上搭建了SuSE Linux系统,使用xshell远程进行连接,一直连接不上,后来百度了一下,连接成功,这里总结一下配置的办法: (1):关闭防火墙 (2):配置sshd( Pas ...

  7. [fw]Die 為什麼不能用現在完成式?

    have PP是表示"從以前到現在"都直在做的事情 Mr. Chen has taught English for 30 years.---表示teach的動作持續了30年,但Mr ...

  8. linux mysql修改数据表结构语法

    MySQL修改表的语法=========================增加列[add 列名]=========================①alter table 表名 add 列名 列类型 列 ...

  9. bat ini文件读取

    借助<bat 读取 ini 文件>文章中的readini.bat实现(请自行前往下载),可满足多个section下Key值查询. ini文件示例 [Server] ServerName = ...

  10. CentOS7安装MySQL5.7.20

    参考1:https://www.cnblogs.com/technology-huangyan/p/10484838.html 参考1:https://blog.csdn.net/aiyowei110 ...