关于java中生产者消费者模式的理解
在说生产者消费者模式之前,我觉得有必要理解一下 Obj.wait(),与Obj.notify()方法。wait()方法是指在持有对象锁的线程调用此方法时,会释放对象锁,同时休眠本线程。notify()方法是持有相同的对象锁来唤醒休眠的线程,使其具有抢占cpu的资格。可以理解同步方法,同步方法的对象锁就是谁调用这个方法,这个对象就是对象锁。
根据李兴华老师的视频讲解,建立一个生产者类,一个消费者类,还有一个Info类,贴上代码:
1.生产者类
package com.company; /**
* Created by Administrator on 2016/8/30.
*/
public class Productor implements Runnable { private Info info; public Productor(Info info) {
this.info = info;
} @Override
public void run() { for (int i=0;i<50;i++)
{
if (i%2==0)
{
// info.setTitle("陶帅");
// info.setContent("一个帅哥");
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
info.set("陶帅","一个帅哥");
}else {
// info.setTitle("可爱的动物");
// info.setContent("草泥马");
info.set("可爱的动物","草泥马");
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
}
}
2.消费者类
package com.company; /**
* Created by Administrator on 2016/8/30.
*/
public class Consumer implements Runnable {
private Info info; public Consumer(Info info) {
this.info = info;
} @Override
public void run() { for (int i=0;i<50;i++)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
info.get();
}
}
}
3.Info类(重点)
package com.company; /**
* Created by Administrator on 2016/8/30.
*/
public class Info {
private String Title;
private String content;
private boolean flag=true;//true表示可以生产不能取走消费,false相反 public synchronized void set(String Titile,String content){
if (!flag)
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.Title=Titile;
this.content=content;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} flag=false;
notify();
} public synchronized void get(){
if (flag)
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.Title+"------->"+this.content);
flag=true;
notify();
} // public String getTitle() {
// return Title;
// }
//
// public void setTitle(String title) {
// Title = title;
// }
//
// public String getContent() {
// return content;
// }
//
// public void setContent(String content) {
// this.content = content;
// }
}
4.测试类
package com.company; public class Main { public static void main(String[] args) {
Info info=new Info();
Productor p=new Productor(info);
Consumer c=new Consumer(info);
new Thread(p).start();
new Thread(c).start();
}
}
总结分析:生产者和消费者两个线程同时抢占CPU,假如消费者先抢到,此时调用get()方法即消费取走,但是此时flag为true,因此会进入wait()方法,所以此时只能是生产者抢占到CPU,根据生产者调用set()方法,生产后执行
flag=false;
notify();
此时生产者和消费者所在的两个线程又站在同一起跑线上了,继续CPU争夺战。如果不幸的消费者又没有抢过生产者,生产者继续执行set();此时flag已经是false了,根据代码
if (!flag)
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
所以生产者只能乖乖的wait();CPU回到消费者这里,循环往复,模式就出来了,完美!
关于java中生产者消费者模式的理解的更多相关文章
- Java设计模式—生产者消费者模式(阻塞队列实现)
生产者消费者模式是并发.多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据.这篇文章我们来看看什么是生产者消费者模式,这个问 ...
- 转:Task任务调度实现生产者消费者模式 (个人理解后文)
纯属个人愚见.欢迎加入反驳(PiDou). 1.前文大致就是,利用Queue配置的一个TaskFactory任务调度器.实现生产者消费者模式的例子..首先我就试了 第一种 FIFO(先进先出)的配置. ...
- java多线程 生产者消费者模式
package de.bvb; /** * 生产者消费者模式 * 通过 wait() 和 notify() 通信方法实现 * */ public class Test1 { public static ...
- java实现生产者消费者模式
生产者消费者问题是一个著名的线程同步问题,该问题描述如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个具有多个缓冲区的缓冲池,生产者将 ...
- java 实现生产者-消费者模式
生产和消费者模式有很多种,现在介绍几种常见的方式 wait/notify实现生产和消费者模式 1.使用wait/notify实现生产和消费者模式: public class Depot { // 实际 ...
- java——利用生产者消费者模式思想实现简易版handler机制
参考教程:http://www.sohu.com/a/237792762_659256 首先说一下这里面涉及到的线程: 1.mainLooper: 这个线程可以理解为消费者线程,里面运行了一个死循环, ...
- Java中生产者与消费者模式
生产者消费者模式 首先来了解什么是生产者消费者模式.该模式也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例.该问题描述了两个共享固定大小缓冲区的线 ...
- Java 生产者消费者模式详细分析
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- 基于Java 生产者消费者模式(详细分析)
Java 生产者消费者模式详细分析 本文目录:1.等待.唤醒机制的原理2.Lock和Condition3.单生产者单消费者模式4.使用Lock和Condition实现单生产单消费模式5.多生产多消费模 ...
随机推荐
- hdu 1756(判断点是否在多边形中)
传送门 题解: 射线法判定点是否在多边形内部: AC代码: #include<iostream> #include<cstdio> #include<cmath> ...
- banner无缝滚动动画,支持左右按钮和小点
HTML: <div class="box"> <ul> <li class="img_cur" > <a href= ...
- js位操作
1.&(与) 都是1才是1 例如:14&15 (14 二进制 1110 15 二进制 1111 &与的结果 1110 ---->结果14) (14& ...
- python---redis缓存页面实现
import tornado.web from controllers.BaseController import BaseRequestHandler import redis pool = red ...
- CSS实现文字竖排排版
CSS实现文字竖排 注意: writing-mode: vertical-rl;存在兼容性问题,在IE上正常,在谷歌的低版本上可能识别不了. 如果文字少的话考虑直接在每一个文字中间加一个<br& ...
- Spring+quartz 实现定时任务job集群配置【原】
为什么要有集群定时任务? 因为如果多server都触发相同任务,又同时执行,那在99%的场景都是不适合的.比如银行每晚24:00都要汇总营业额.像下面3台server同时进行汇总,最终计算结果可能是真 ...
- 01-单一职责原则(SPR)
1. 背景 类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障. 2. 定义 不要存在多于一个导致类 ...
- C#自绘蒙版控件,带延时隐藏显示,拷贝底图功能
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; u ...
- PreparedStatement 基于mysql数据库做分页查询和统计查询
分页查询: 统计查询:
- jsp中的JSTL与EL表达式用法
JSTL (JSP Standard Tag Library ,JSP标准标签库) JSTL标签库分为5类:JSTL核心标签库.JSTL函数标签库.数据库标签库.I18N格式化标签库.XML标签库. ...