1.管程法:
生产者:负责生产数据的模块(可能是方法,对象,线程,进程)
消费者:负责处理数据的模块(可能是方法,对象,线程,进程)
缓冲区:消费者不能直接使用生产者的数据,他们之间有个缓冲区,生产者将生产好的数据放入缓冲区,消费者从缓冲区拿出数据
思路:
1.首先有一个生产者,消费者、生产者只顾生产,消费者只管消费
2.利用了一个缓冲区,缓冲了一个10个大小的数组
3.有个方法叫放入产品,产品丢进来的时候,我们判断一下缓冲区有没有满,如果满了的话,生产者就要等待了,
如果没有满,就将产品放进去,放进去之后有产品了,赶紧通知消费者消费
4.消费者就判断下能不能消费呢,有没有东西,有东西的话,我就可以直接消费,消费完了,就赶紧通知生产者生产。
如果没有东西呢,消费者就等待。等待生产者去通知他,生产者通知了,他就可以解除等待了,所以在这一块存在我们的wait()和notify()。
这里的wait()和notify()都是Object提供的:
wait()导致当前线程等待,直到另一个线程调用该对象的notify()或notifyAll()方法。
notify()唤醒正在等待对象监视器的单个线程。
一旦加了wait()之后同样是进入了阻塞状态,但是这个阻塞和之前的sleep()不一样,它会释放锁,被wait()的线程可以把这个锁交给其他线程去用,否则这个资源就一直被其持有了。
思路有了那么就开始代码部分了:
(1)创建生产者
// 生产者
class Productor extends Thread{
SynContainer container;
public Productor(SynContainer container){
this.container = container;
}
// 生产
@Override
public void run() {
for (int i = 0; i < 100; i++) {
container.push(new Bug(i));
System.out.println("生产了"+i+"个bug");
}
}
}
(2)创建消灭者
// 消灭bug者
class Consumer extends Thread{
SynContainer container;
public Consumer(SynContainer container){
this.container = container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("消灭了-->"+container.pop().id+"个bug");
}
}
}
(3)创建bug区(产品区)
// bug产品
class Bug{
int id;// bug编号
public Bug(int id){
this.id = id;
}
}
(4)创建同步代码块(缓冲区)
// 缓冲区
class SynContainer{
// 需要一个容器大小
Bug[] bugs = new Bug[10];
// 容器计算器
int count = 0;
// 生产者放入bug
public synchronized void push(Bug bug){
// 如果容器满了,就需要等待消灭bug
if(count==bugs.length){
// 通知消灭bug者消灭,生产bug等待
try {
//导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 如果没有满,我们就需要继续生产bug
bugs[count] = bug;
count++;
// 可以通知消灭者消灭了
this.notifyAll();
// notifyAll唤醒正在等待对象监视器的所有线程。
}
// 消灭者消灭bug
public synchronized Bug pop(){
// 判断能否消灭
if (count == 0){
// 等待生产者生产,消灭者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 如果可以消灭
count--;
Bug bug = bugs[count];
// 消灭完了,通知生产者生产
return bug;
}
}
保证容器中没有产品的时候生产产品,不能消费;容器中产品满了的时候,不能再去生产产品
(5)创建测试类
public class Test {
public static void main(String[] args) {
SynContainer container = new SynContainer();
new Productor(container).start();
new Consumer(container).start();
}
}
(6)测试
很完美的把全部bug都消灭了
2.信号灯法:
先来理解下信号灯法是什么意思:来判断一个标志位flag,如果为true,就让他等待、如果为false,就让他去通知另外一个人、把两人衔接起来,就像咱们的信号灯红灯停,绿灯行,通过这样一个判断方式,只要来判断什么瑞后让他等待,什么时候将他唤醒就ok。
话不多说直接上代码^^
package com.macro.mall.bo;
//测试生产者消费者问题2:信号灯法,通过标志位解决
public class Test {
public static void main(String[] args) {
TV tv = new TV();
new Player(tv).start();
new Watcher(tv).start();
}
}
//生产者-->演员
class Player extends Thread {
TV tv;
public Player(TV tv) {
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if (i % 2 == 0) {
this.tv.play("什么是快乐星球");
} else {
this.tv.play("如果你想知道什么是快乐星球的话,那我就带你研究研究");
}
}
}
}
//消费者-->观众
class Watcher extends Thread {
TV tv;
public Watcher(TV tv) {
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
tv.watch();
}
}
}
//产品-->节目
class TV {
//演员表演,观众等待 T
//观众观看,演员等待 F
String voice; // 表演的节目
boolean flag = true;
//表演
public synchronized void play(String voice) {
if (!flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("演员表演了:" + voice);
//通知观众观看
this.notifyAll();
this.voice = voice;
this.flag = !this.flag;
}
//观看
public synchronized void watch() {
if (flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("观看了:" + voice);
//通知演员表演
this.notifyAll();
this.flag = !this.flag;
}
}
第一篇文章,感谢家人们的阅读
本文实例讲述了Laravel框架源码解析之反射的使用。分享给大家供大家参考,具体如...
4月11日20:30~22:00通过腾讯会议进行了第二次在线学习讨论我把学习笔记整理一下...
DELETEFROMTablesWHEREIDNOTIN(SELECTMin(ID)FROMTablesGROUPBYName) Min的话保...
正则忽略大小写 – RegexOptions.IgnoreCase 例如: 复制代码 代码如下: Str = R...
项目中用到的一些特殊字符和图标 html代码 XML/HTML Code 复制内容到剪贴板 div ...
复制代码 代码如下: % URL="http://news.163.com/special/00011K6L/rss_newstop....
错误描述: 在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报...
上篇文章给大家介绍了 Java正则表达式匹配,替换,查找,切割的方法 ,接下来,...
Elasticsearch 是通过 Lucene 的倒排索引技术实现比关系型数据库更快的过滤。特...
工具:Eclipse,Oracle,smartupload.jar;语言:jsp,Java;数据存储:Oracle。...