【1】生产者-消费者模型的三种实现方式

(手写生产者消费者模型,写BlockingQueue较简便 )

1、背景                                                                    

生产者生产数据到缓冲区中,消费者从缓冲区中取数据。

如果缓冲区已经满了,则生产者线程阻塞;

如果缓冲区为空,那么消费者线程阻塞。

2、方式一:synchronized、wait和notify

add()和remove()方法是synchronized 的

package producerConsumer;
//wait 和 notify
public class ProducerConsumerWithWaitNofity {public static void main(String[] args) {Resource resource = new Resource();//生产者线程ProducerThread p1 = new ProducerThread(resource);ProducerThread p2 = new ProducerThread(resource);ProducerThread p3 = new ProducerThread(resource);//消费者线程ConsumerThread c1 = new ConsumerThread(resource);//ConsumerThread c2 = new ConsumerThread(resource);//ConsumerThread c3 = new ConsumerThread(resource);
    p1.start();p2.start();p3.start();c1.start();//c2.start();//c3.start();
    }}
/*** 公共资源类* @author **/
class Resource{//重要//当前资源数量private int num = 0;//资源池中允许存放的资源数目private int size = 10;/*** 从资源池中取走资源*/public synchronized void remove(){if(num > 0){num--;System.out.println("消费者" + Thread.currentThread().getName() +"消耗一件资源," + "当前线程池有" + num + "个");notifyAll();//通知生产者生产资源}else{try {//如果没有资源,则消费者进入等待状态
                wait();System.out.println("消费者" + Thread.currentThread().getName() + "线程进入等待状态");} catch (InterruptedException e) {e.printStackTrace();}}}/*** 向资源池中添加资源*/public synchronized void add(){if(num < size){num++;System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有" + num + "个");//通知等待的消费者
            notifyAll();}else{//如果当前资源池中有10件资源try{wait();//生产者进入等待状态,并释放锁System.out.println(Thread.currentThread().getName()+"线程进入等待");}catch(InterruptedException e){e.printStackTrace();}}}
}
/*** 消费者线程*/
class ConsumerThread extends Thread{private Resource resource;public ConsumerThread(Resource resource){this.resource = resource;}@Overridepublic void run() {while(true){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}resource.remove();}}
}
/*** 生产者线程*/
class ProducerThread extends Thread{private Resource resource;public ProducerThread(Resource resource){this.resource = resource;}@Overridepublic void run() {//不断地生产资源while(true){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}resource.add();}}}
View Code

 

3、方式二:lock和condition的await、signalAll     

package producerConsumer;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/*** 使用Lock 和 Condition解决生产者消费者问题* @author tangzhijing**/
public class LockCondition {public static void main(String[] args) {Lock lock = new ReentrantLock();Condition producerCondition = lock.newCondition();Condition consumerCondition = lock.newCondition();Resource2 resource = new Resource2(lock,producerCondition,consumerCondition);//生产者线程ProducerThread2 producer1 = new ProducerThread2(resource);//消费者线程ConsumerThread2 consumer1 = new ConsumerThread2(resource);ConsumerThread2 consumer2 = new ConsumerThread2(resource);ConsumerThread2 consumer3 = new ConsumerThread2(resource);producer1.start();consumer1.start();consumer2.start();consumer3.start();}
}
/*** 消费者线程*/
class ConsumerThread2 extends Thread{private Resource2 resource;public ConsumerThread2(Resource2 resource){this.resource = resource;//setName("消费者");
    }public void run(){while(true){try {Thread.sleep((long) (1000 * Math.random()));} catch (InterruptedException e) {e.printStackTrace();}resource.remove();}}
}
/*** 生产者线程* @author tangzhijing**/
class ProducerThread2 extends Thread{private Resource2 resource;public ProducerThread2(Resource2 resource){this.resource = resource;setName("生产者");}public void run(){while(true){try {Thread.sleep((long) (1000 * Math.random()));} catch (InterruptedException e) {e.printStackTrace();}resource.add();}}
}
/*** 公共资源类* @author tangzhijing**/
class Resource2{private int num = 0;//当前资源数量private int size = 10;//资源池中允许存放的资源数目private Lock lock;private Condition producerCondition;private Condition consumerCondition;public Resource2(Lock lock, Condition producerCondition, Condition consumerCondition) {this.lock = lock;this.producerCondition = producerCondition;this.consumerCondition = consumerCondition;}/*** 向资源池中添加资源*/public void add(){lock.lock();try{if(num < size){num++;System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有" + num + "个");//唤醒等待的消费者
                consumerCondition.signalAll();}else{//让生产者线程等待try {producerCondition.await();System.out.println(Thread.currentThread().getName() + "线程进入等待");} catch (InterruptedException e) {e.printStackTrace();}}}finally{lock.unlock();}}/*** 从资源池中取走资源*/public void remove(){lock.lock();try{if(num > 0){num--;System.out.println("消费者" + Thread.currentThread().getName() + "消耗一件资源," + "当前资源池有" + num + "个");producerCondition.signalAll();//唤醒等待的生产者}else{try {consumerCondition.await();System.out.println(Thread.currentThread().getName() + "线程进入等待");} catch (InterruptedException e) {e.printStackTrace();}//让消费者等待
            }}finally{lock.unlock();}}}
View Code

 

4、方式三:BlockingQueue       

package producerConsumer;import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;//使用阻塞队列BlockingQueue解决生产者消费者
public class BlockingQueueConsumerProducer {public static void main(String[] args) {Resource3 resource = new Resource3();//生产者线程ProducerThread3 p = new ProducerThread3(resource);//多个消费者ConsumerThread3 c1 = new ConsumerThread3(resource);ConsumerThread3 c2 = new ConsumerThread3(resource);ConsumerThread3 c3 = new ConsumerThread3(resource);p.start();c1.start();c2.start();c3.start();}
}
/*** 消费者线程* @author tangzhijing**/
class ConsumerThread3 extends Thread {private Resource3 resource3;public ConsumerThread3(Resource3 resource) {this.resource3 = resource;//setName("消费者");
    }public void run() {while (true) {try {Thread.sleep((long) (1000 * Math.random()));} catch (InterruptedException e) {e.printStackTrace();}resource3.remove();}}
}
/*** 生产者线程* @author tangzhijing**/
class ProducerThread3 extends Thread{private Resource3 resource3;public ProducerThread3(Resource3 resource) {this.resource3 = resource;//setName("生产者");
    }public void run() {while (true) {try {Thread.sleep((long) (1000 * Math.random()));} catch (InterruptedException e) {e.printStackTrace();}resource3.add();}}
}
class Resource3{private BlockingQueue<Integer> resourceQueue = new LinkedBlockingQueue<>(10);/*** 向资源池中添加资源*/public void add(){try {resourceQueue.put(1); //1当做生产和消费的Integer资源System.out.println("生产者" + Thread.currentThread().getName()+ "生产一件资源," + "当前资源池有" + resourceQueue.size() + "个资源");} catch (InterruptedException e) {e.printStackTrace();}}/*** 向资源池中移除资源*/public void remove(){try {resourceQueue.take();System.out.println("消费者" + Thread.currentThread().getName() + "消耗一件资源," + "当前资源池有" + resourceQueue.size() + "个资源");} catch (InterruptedException e) {e.printStackTrace();}}
}
View Code

 

转载于:https://www.cnblogs.com/twoheads/p/10137263.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/412589.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot mybatis-plus 配置 yml 、druid 配置 yml 、mybatis-plus 代码生成

大家好&#xff0c;我是烤鸭&#xff1a; 今天分享一下 springboot mybatis-plus 和 druid 的yml 配置文件。 pom <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency…

[css] 说说你对媒体查询的理解

[css] 说说你对媒体查询的理解 当年做响应式布局的时候用过媒介查询&#xff0c;media query。包括现在有的时候为了兼容也会用到一些&#xff0c;查找对应范围使用不同的样式个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定…

Spring Boot 2.1 版本变化[翻译]

大家好&#xff0c;我是烤鸭&#xff1a; ​ 最近在把低版本的springboot项目升级&#xff0c;正好翻译了下springboot 2.1-2.3 版本的更新日志。 ​ Github 原文&#xff1a;https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1-Release-Notes ​ 2.2 版…

实验吧Web-易-天网管理系统(php弱类型,==号)

打开网页&#xff0c;查看源码&#xff0c;看到 <!-- $test$_GET[username]; $testmd5($test); if($test0) --> 说明用户名需要加密之后为0。 对于PHP的号&#xff0c;在使用 运算符对两个字符串进行松散比较时&#xff0c;PHP会把类数值的字符串转换为数值进行比较&…

[css] 你知道的等高布局有多少种?写出来

[css] 你知道的等高布局有多少种&#xff1f;写出来 flex拉伸display: flex; align-items: stretch;padding margin抵消 然后background-clip默认是border-box所以会在被抵消的位置依然显示背景 造成等高假象.box,.box2{float: left;width: 100px; } .box {background: #cccccc…

Spring Boot 2.2版本变化[翻译]

大家好&#xff0c;我是烤鸭&#xff1a; ​ 最近在把低版本的springboot项目升级&#xff0c;正好翻译了下springboot 2.1-2.3 版本的更新日志。 ​ Github 原文&#xff1a;https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.2-Release-Notes ​ 2.1 版…

[css] 手写一个满屏品字布局的方案

[css] 手写一个满屏品字布局的方案 <!DOCTYPE html> <html><head><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta charset"UTF-8"><link rel"stylesheet" href"st…

个人的博客搭建(持续更新)

最近的CSDN的博客阅读体验非常的糟糕&#xff0c;恰好自己也一直想搭建一个属于自己的网站&#xff0c;放下自己的技术心得情感体会&#xff0c;从零开始慢慢搭建项目磨练技术&#xff0c;以后也把自己新习得的技术放在里面增加自己的学习乐趣。 一&#xff0c;搭建基本的项目模…

Spring Boot 2.3 版本变化[翻译]

大家好&#xff0c;我是烤鸭&#xff1a; ​ 最近在把低版本的springboot项目升级&#xff0c;正好翻译了下springboot 2.1-2.3 版本的更新日志。 ​ Github 原文&#xff1a;https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes ​ 2.1 版…

[css] span与span之间有看不见的空白间隔是什么原因引起的?有什么解决办法?

[css] span与span之间有看不见的空白间隔是什么原因引起的&#xff1f;有什么解决办法&#xff1f; 可能是设置成了inline-block。 第一种解决方案是&#xff0c;去掉span标签内的空白。 第二种解决方案是&#xff0c;设置margin负值&#xff0c;但要根据字体调整&#xff0c;…

[css] 重置(初始化)css的作用是什么?

[css] 重置&#xff08;初始化&#xff09;css的作用是什么&#xff1f; 这是一个&#xff0c;还有就是视觉问题&#xff0c;浏览器默认样式会影响我们的设计还原&#xff0c;而且默认样式一般不够美观&#xff0c;满足不了定制化的视觉需求&#xff0c;达不到视觉产品的信息传…

《代码整洁之道 Clean Architecture》-读书笔记

大家好&#xff0c;我是烤鸭&#xff1a; 关于《代码整洁之道》&#xff0c;记录一下读书笔记。 代码整洁之道第一章 整洁代码整洁代码的艺术第二章 有意义的命名避免误导有意义的区分使用读得出来和可搜索的名字避免使用编码第三章 函数第四章 注释第五章 格式第六章 对象和数…

用Java实现图片验证码功能

一、什么是图片验证码&#xff1f; 可以参考下面这张图&#xff1a; 我们在一些网站注册的时候&#xff0c;经常需要填写以上图片的信息。 1、图片生成实体类&#xff1a; 1 package com.hexianwei.graphic;2 3 import java.awt.Color;4 import java.awt.Font;5 import java.aw…

[css] 怎么让英文单词的首字母大写?

[css] 怎么让英文单词的首字母大写&#xff1f; 楼上用的没问题&#xff0c;学习嘛&#xff0c;那我就来扩展一下。text-transform 属性控制文本的大小写&#xff0c;是CSS2.1的属性&#xff0c;兼容性问题不大。 属性值是关键字&#xff0c;有41种&#xff0c;这个1是实验性属…

Zuul 1.x 升级 springcloud gateway 2.x 遇到的一点问题

大家好&#xff0c;我是烤鸭&#xff1a; 今天分享 Zuul 1.x 升级 springcloud gateway 2.x 遇到的一点问题。 介绍 zuul 和springcloud gateway 都是比较优秀的网关&#xff0c;而 zuul 1.x 采用的是 servlet 模型&#xff0c;gate 采用的是 reactor模型&#xff0c;效率和资…

render_template 网页模板

模板简单介绍&#xff1a; 视图函数&#xff1a;视图函数就是装饰器所装饰的方法&#xff0c;视图函数的主要作用是生成请求的响应&#xff0c;这是最简单的请求。实际上&#xff0c;视图函数有两个作用&#xff1a;处理业务逻辑和返回响应内容。在大型应用中&#xff0c;把业务…

[css] 怎么才能让图文不可复制?

[css] 怎么才能让图文不可复制&#xff1f; -webkit-user-select: none; -ms-user-select: none; -moz-user-select: none; -khtml-user-select: none; user-select: none;个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷…

nacos配置刷新失败导致的cpu上升和频繁重启,nacos配置中心源码解析

大家好&#xff0c;我是烤鸭&#xff1a; nacos 版本 1.3.2&#xff0c;先说下结论&#xff0c;频繁重启的原因确实没有找到&#xff0c;跟nacos有关&#xff0c;日志没有保留多少&#xff0c;只能从源码找下头绪(出问题的版本 server用的是 nacos 1.1&#xff0c;nacos-client…

nova— 计算服务

一、nova介绍&#xff1a; Nova 是 OpenStack 最核心的服务&#xff0c;负责维护和管理云环境的计算资源。OpenStack 作为 IaaS 的云操作系统&#xff0c;虚拟机生命周期管理也就是通过 Nova 来实现的。用途与功能 :1) 实例生命周期管理2) 管理计算资源3) 网络和认证管理4)REST…

[css] 写出你知道的CSS水平和垂直居中的方法

[css] 写出你知道的CSS水平和垂直居中的方法 flex布局水平垂直居中:<!-- html --> <div class"outer"><div class"inner"></div> </div>/*css*/ .outer{display:flex;width:200px;height:200px;border:1px solid red; } .…