java实现生产者/消费者的三种方式
package com.wenki.thread; import java.util.LinkedList; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ProductAndConsume { public static void main(String[] args) { ProductAndConsume o = new ProductAndConsume(); // Storage storage = o.new StorageOne(); // Storage storage = o.new StorageTwo(); Storage storage = o.new StorageThree(); Consumer consumer1 = o.new Consumer(storage); Consumer consumer2 = o.new Consumer(storage); Producter producter1 = o.new Producter(storage); Producter producter2 = o.new Producter(storage); Producter producter3 = o.new Producter(storage); consumer1.start(); consumer2.start(); producter1.start(); producter2.start(); producter3.start(); } class Producter extends Thread{ Storage storage; public Producter(Storage storage) { this.storage = storage; } public void product(){ this.storage.product(); } @Override public void run() { for(;;){ product(); } } } class Consumer extends Thread{ Storage storage; public Consumer(Storage storage){ this.storage = storage; } public void consume(){ this.storage.consume(); } @Override public void run() { for(;;){ consume(); } } } interface Storage{ int MAX_SIZE = 100; LinkedList<Object> list = new LinkedList<Object>(); public abstract void product(); public abstract void consume(); } //第一种方式 wait() + notify() class StorageOne implements Storage{ @Override public void product() { synchronized (list) { while(list.size() == MAX_SIZE){ try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } if(list.add(new Object())){ System.out.println("生产 ### 产品数量 : " + list.size()); //通知消费者可以继续消费 list.notifyAll(); } try { TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override public void consume() { synchronized (list) { while(list.size() == 0){ try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } if(list.remove() != null){ System.out.println("消费 ### 产品数量: " + list.size()); //通知生产者可以继续生产 list.notifyAll(); } try { TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } //第二种方式 await() + signal() class StorageTwo implements Storage{ Lock lock = new ReentrantLock(); Condition fully = lock.newCondition(); Condition empty = lock.newCondition(); @Override public void product() { lock.lock(); try{ while(list.size() == MAX_SIZE){ fully.await(); } if(list.add(new Object())){ System.out.println("生产 ### 产品数量 : " + list.size()); empty.signalAll(); } TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } @Override public void consume() { lock.lock(); try{ while(list.size() == 0){ empty.await(); } if(list.remove() != null){ System.out.println("消费 ### 产品数量: " + list.size()); fully.signalAll(); } TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }finally{ lock.unlock(); } } } //第三种 BlockingQueue 阻塞队列 class StorageThree implements Storage{ LinkedBlockingQueue<Object> list = new LinkedBlockingQueue<Object>(MAX_SIZE); @Override public void product() { try { list.put(new Object()); System.out.println("生产 ### 产品数量 : " + list.size()); TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void consume() { try { if(list.take() != null){ System.out.println("消费 ### 产品数量: " + list.size()); } TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
java实现生产者/消费者的三种方式的更多相关文章
- java 实现md5加密的三种方式与解密
java 实现md5加密的三种方式 CreateTime--2018年5月31日15点04分 Author:Marydon 一.解密 说明:截止文章发布,Java没有实现解密,但是已有网站可以免费 ...
- java中遍历集合的三种方式
第一种遍历集合的方式:将集合变为数组 package com.lw.List; import java.util.ArrayList; import java.util.List; import ja ...
- java加载配置文件的三种方式
比如我们要加载db.properties文件 如图: 比如我们要加载source目录下的db.properties文件.就有以下几种方式 第一种是文件io流: public static void l ...
- JAVA实现Base64编码的三种方式
摘要: Javabase64编码的三种方式 有如下三种方式: 方式一:commons-codec.jar Java代码 1. String base64String="whuang12 ...
- Java通过JDBC连接数据库的三种方式!!!并对数据库实现增删改查
前言 java连接数据库完整流程为: 1,获得驱动(driver),数据库连接(url),用户名(username),密码(password)基本信息的三种方式. 2,通过获得的信息完成JDBC实现连 ...
- java实现HTTP请求的三种方式
目前JAVA实现HTTP请求的方法用的最多的有两种:一种是通过HTTPClient这种第三方的开源框架去实现.HTTPClient对HTTP的封装性比较不错,通过它基本上能够满足我们大部分的需求,Ht ...
- 【转载】java实现HTTP请求的三种方式
目前JAVA实现HTTP请求的方法用的最多的有两种:一种是通过HTTPClient这种第三方的开源框架去实现.HTTPClient对HTTP的封装性比较不错,通过它基本上能够满足我们大部分的需求,Ht ...
- Java 实现线程安全的三种方式
一个程序在运行起来的时候会转换成进程,通常含有多个线程. 通常情况下,一个进程中的比较耗时的操作(如长循环.文件上传下载.网络资源获取等),往往会采用多线程来解决. 比如显示生活中,银行取钱问题.火车 ...
- HTTP:Java实现HTTP请求的三种方式
目前JAVA实现HTTP请求的方法用的最多的有两种: 一种是通过HTTPClient这种第三方的开源框架去实现.HTTPClient对HTTP的封装性比较不错,通过它基本上能够满足我们大部分的需求,H ...
随机推荐
- nyoj 第几是谁
第几是谁? 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 现在有"abcdefghijkl"12个字符,将其按字典序排列,如果给出任意一种排列, ...
- github提交代码到服务器的方法
第一种情况,没有冲突:1.git add .//进入到center的项目下将本地文件打包的意思2.git pull origin dev//将服务器的代码下载到本地如果是最新的会提示Already u ...
- python安装及写一个简单的验证码组件(配合node)
1.安装Python 到官网下载响应系统的版本(这里以windows为例):https://www.python.org/downloads/windows/ 然后就是不断地"下一步&quo ...
- GIT入门笔记(15)- 链接到私有GitLab仓库
GitLab是利用 Ruby on Rails 一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目.它拥有与Github类似的功能,能够浏览源代码,管理 ...
- JSON(五)——同步请求中使用JSON格式字符串进行交互(不太常见的用法)
在同步请求中使用JSON格式进行数据交互的场景并不多,同步请求是浏览器直接与服务器进行数据交互的大多是用jsp的标签jstl和el表达式对请求中的数据进行数据的渲染.我也是在一次开发中要从其它服务器提 ...
- python爬虫动态html selenium.webdriver
python爬虫:利用selenium.webdriver获取渲染之后的页面代码! 1 首先要下载浏览器驱动: 常用的是chromedriver 和phantomjs chromedirver下载地址 ...
- Vue框架下的node.js安装教程
Vue框架下的node.js安装教程 python服务器.php ->aphche.java ->tomcat. iis -->它是一个可以运行JAVASCRIPTR 的运行环 ...
- Java-Maven(六):Eclipse中Maven插件的命令操作
之前几个章节学习了maven的概念,及maven插件安装后如何创建工程,那么maven工程中是如何使用maven命令呢?本章节将会学习这个话题. 在pom.xml中配置maven命令插件 如果向在ma ...
- jQuery 事件绑定 和 JavaScript 原生事件绑定
总结一下:jQuery 事件绑定 和 JavaScript 原生事件绑定 及 区别 jQuery 事件绑定 jQuery 中提供了四种事件监听绑定方式,分别是 bind.live.delegate.o ...
- JavaScript 中常见的内存泄露陷阱(摘)
内存泄露是每个开发者最终都不得不面对的问题.即便使用自动内存管理的语言,你还是会碰到一些内存泄漏的情况.内存泄露会导致一系列问题,比如:运行缓慢,崩溃,高延迟,甚至一些与其他应用相关的问题. 什么是内 ...