Java线程设计模式(五)
多线程的设计模式:Future模式、Master-Worker模式,生产消费者模式
- public interface Data {
- String getRequest();
- }
- public class FutureClient {
- public Data request(final String queryStr){
- //1 我想要一个代理对象(Data接口的实现类)先返回给发送请求的客户端,告诉他请求已经接收到,可以做其他的事情
- final FutureData futureData = new FutureData();
- //2 启动一个新的线程,去加载真实的数据,传递给这个代理对象
- new Thread(new Runnable() {
- @Override
- public void run() {
- //3 这个新的线程可以去慢慢的加载真实对象,然后传递给代理对象
- RealData realData = new RealData(queryStr);
- futureData.setRealData(realData);
- }
- }).start();
- return futureData;
- }
- }
- public class FutureData implements Data{
- private RealData realData ;
- private boolean isReady = false;
- public synchronized void setRealData(RealData realData) {
- //如果已经装载完毕了,就直接返回
- if(isReady){
- return;
- }
- //如果没装载,进行装载真实对象
- this.realData = realData;
- isReady = true;
- //进行通知
- notify();
- }
- @Override
- public synchronized String getRequest() {
- //如果没装载好 程序就一直处于阻塞状态
- while(!isReady){
- try {
- wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- //装载好直接获取数据即可
- return this.realData.getRequest();
- }
- }
- public class RealData implements Data{
- private String result ;
- public RealData (String queryStr){
- System.out.println("根据" + queryStr + "进行查询,这是一个很耗时的操作..");
- try {
- Thread.sleep(5000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("操作完毕,获取结果");
- result = "查询结果";
- }
- @Override
- public String getRequest() {
- return result;
- }
- }
- public class Main {
- public static void main(String[] args) throws InterruptedException {
- FutureClient fc = new FutureClient();
- Data data = fc.request("请求参数");
- System.out.println("请求发送成功!");
- System.out.println("做其他的事情...");
- String result = data.getRequest();
- System.out.println(result);
- }
- }
- import java.util.HashMap;
- import java.util.Map;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.ConcurrentLinkedQueue;
- public class Master {
- //1 有一个盛放任务的容器
- private ConcurrentLinkedQueue<Task> workQueue=new ConcurrentLinkedQueue<Task>();
- //2 需要有一个盛放worker的集合
- private HashMap<String,Thread> workers =new HashMap<String, Thread>();
- //3 需要有一个盛放每一个worker执行任务的结果集合
- private ConcurrentHashMap<String,Object> resultMap=new ConcurrentHashMap<String, Object>();
- //4 构造方法
- public Master(Worker worker,int workerCount){
- worker.setWorkQueue(this.workQueue);
- worker.setResultMap(this.resultMap);
- for(int i = 0; i < workerCount; i ++){
- this.workers.put(Integer.toString(i), new Thread(worker));
- }
- }
- //5 需要一个提交任务的方法
- public void submit(Task task) {
- this.workQueue.add(task);
- }
- //6 需要有一个执行的方法,启动所有的worker方法去执行任务
- public void execute(){
- for(Map.Entry<String,Thread> me: workers.entrySet()){
- me.getValue().start();
- }
- }
- //7 判断是否运行结束的方法
- public boolean isComplete() {
- for(Map.Entry<String, Thread> me : workers.entrySet()){
- if(me.getValue().getState() != Thread.State.TERMINATED){
- return false;
- }
- }
- return true;
- }
- //8 计算结果方法
- public int getResult() {
- int priceResult = 0;
- for(Map.Entry<String, Object> me : resultMap.entrySet()){
- priceResult += (Integer)me.getValue();
- }
- return priceResult;
- }
- }
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.ConcurrentLinkedQueue;
- public class Worker implements Runnable{
- private ConcurrentLinkedQueue<Task> workQueue;
- private ConcurrentHashMap<String,Object> resultMap;
- public void setWorkQueue(ConcurrentLinkedQueue<Task> workQueue) {
- this.workQueue=workQueue;
- }
- public void setResultMap(ConcurrentHashMap<String,Object> resultMap){
- this.resultMap=resultMap;
- }
- @Override
- public void run(){
- while (true){
- Task input=this.workQueue.poll();
- if(input==null) break;
- Object output=handle(input);
- this.resultMap.put(Integer.toString(input.getId()),output);
- }
- }
- private Object handle(Task input){
- Object output=null;
- try {
- //处理任务的耗时。。 比如说进行操作数据库。。。
- Thread.sleep(500);
- output = input.getPrice();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- return output;
- }
- }
- public class Task {
- private int id;
- private int price ;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public int getPrice() {
- return price;
- }
- public void setPrice(int price) {
- this.price = price;
- }
- }
- import java.util.Random;
- public class Main {
- public static void main(String[] args) {
- Master master = new Master(new Worker(), 20);
- Random r = new Random();
- for (int i = 1; i <= 100; i++) {
- Task t = new Task();
- t.setId(i);
- t.setPrice(r.nextInt(1000));
- master.submit(t);
- }
- master.execute();
- long start = System.currentTimeMillis();
- while (true) {
- if (master.isComplete()) {
- long end = System.currentTimeMillis() - start;
- int priceResult = master.getResult();
- System.out.println("最终结果:" + priceResult + ", 执行时间:" + end);
- break;
- }
- }
- }
- }
生产者-消费者
- public final class Data {
- private String id;
- private String name;
- public Data(String id, String name){
- this.id = id;
- this.name = name;
- }
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- @Override
- public String toString(){
- return "{id: " + id + ", name: " + name + "}";
- }
- }
- import java.util.Random;
- import java.util.concurrent.BlockingQueue;
- public class Consumer implements Runnable{
- private BlockingQueue<Data> queue;
- public Consumer(BlockingQueue queue){
- this.queue=queue;
- }
- //随机对象
- private static Random r = new Random();
- @Override
- public void run() {
- while(true){
- try {
- //获取数据
- Data data = this.queue.take();
- //进行数据处理。休眠0 - 1000毫秒模拟耗时
- Thread.sleep(r.nextInt(1000));
- System.out.println("当前消费线程:" + Thread.currentThread().getName() + ", 消费成功,消费数据为id: " + data.getId());
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- public class Provider implements Runnable{
- //共享缓存区
- private BlockingQueue<Data> queue;
- //多线程间是否启动变量,有强制从主内存中刷新的功能。即时返回线程的状态
- private volatile boolean isRunning = true;
- //id生成器
- private static AtomicInteger count = new AtomicInteger();
- //随机对象
- private static Random r = new Random();
- public Provider(BlockingQueue queue){
- this.queue = queue;
- }
- @Override
- public void run() {
- while(isRunning){
- try {
- //随机休眠0 - 1000 毫秒 表示获取数据(产生数据的耗时)
- Thread.sleep(r.nextInt(1000));
- //获取的数据进行累计...
- int id = count.incrementAndGet();
- //比如通过一个getData方法获取了
- Data data = new Data(Integer.toString(id), "数据" + id);
- System.out.println("当前线程:" + Thread.currentThread().getName() + ", 获取了数据,id为:" + id + ", 进行装载到公共缓冲区中...");
- if(!this.queue.offer(data, 2, TimeUnit.SECONDS)){
- System.out.println("提交缓冲区数据失败....");
- //do something... 比如重新提交
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- public void stop(){
- this.isRunning = false;
- }
- }
- public class Main {
- public static void main(String[] args) throws Exception {
- //内存缓冲区
- BlockingQueue<Data> queue = new LinkedBlockingQueue<Data>(10);
- //生产者
- Provider p1 = new Provider(queue);
- Provider p2 = new Provider(queue);
- Provider p3 = new Provider(queue);
- //消费者
- Consumer c1 = new Consumer(queue);
- Consumer c2 = new Consumer(queue);
- Consumer c3 = new Consumer(queue);
- //创建线程池运行,这是一个缓存的线程池,可以创建无穷大的线程,没有任务的时候不创建线程。空闲线程存活时间为60s(默认值)
- ExecutorService cachePool = Executors.newCachedThreadPool();
- cachePool.execute(p1);
- cachePool.execute(p2);
- cachePool.execute(p3);
- cachePool.execute(c1);
- cachePool.execute(c2);
- cachePool.execute(c3);
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- p1.stop();
- p2.stop();
- p3.stop();
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- // cachePool.shutdown();
- // cachePool.shutdownNow();
- }
- }
Java线程设计模式(五)的更多相关文章
- java 线程(五)线程安全 Lock接口
package cn.sasa.demo3; import java.util.concurrent.ExecutionException; public class ThreadDemo { pub ...
- java线程的五种状态
五种状态 开始状态(new) 就绪状态(runnable) 运行状态(running) 阻塞状态(blocked) 结束状态(dead) 状态变化 1.线程刚创建时,是new状态 2.线程调用了sta ...
- java常用设计模式五:建造者模式
1.定义 是一种对象构建的设计模式,它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象. 产品类:一般是一个较为复杂的对象,也就是说创建对象的 ...
- Java线程的五种状态详解
状态转换图 1.new状态:通过new关键字创建了Thread或其子类的对象 2.Runnable状态:即就绪状态.可从三种状态到达,new状态的Thread对象调用start()方法,Running ...
- 细说进程五种状态的生老病死——双胞胎兄弟Java线程
java线程的五种状态其实要真正高清,只需要明白计算机操作系统中进程的知识,原理都是相同的. 系统根据PCB结构中的状态值控制进程. 单CPU系统中,任一时刻处于执行状态的进程只有一个. 进程的五种状 ...
- java常用设计模式总览
一.java的设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式. 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组 ...
- java线程池与五种常用线程池策略使用与解析
背景:面试中会要求对5中线程池作分析.所以要熟知线程池的运行细节,如CachedThreadPool会引发oom吗? java线程池与五种常用线程池策略使用与解析 可选择的阻塞队列BlockingQu ...
- Java线程创建形式 Thread构造详解 多线程中篇(五)
Thread作为线程的抽象,Thread的实例用于描述线程,对线程的操纵,就是对Thread实例对象的管理与控制. 创建一个线程这个问题,也就转换为如何构造一个正确的Thread对象. 构造方法列表 ...
- Java多线程(五)线程的生命周期
点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...
随机推荐
- Noip2019暑期训练2 反思
经过两次测试,通过深刻的反思,我主要发现了以下易犯错误: 1.做题目时过于追求速度,导致好几处代码都出现手误打错的现象!而且,千万不要图快.图方便就复制粘贴,非常容易出错!(例如T3-party中直接 ...
- vue使用axios发送请求,都会发送两次请求
vue 使用axios,每次的请求都会发送两次,第一次的请求头为options CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sha ...
- 分享一些好用的 Chrome 扩展
阅读本文大概需要 2.8 分钟. 前言 使用浏览器扩展程序可以使你的工作效率提高数倍不止,那么下面我就向大家分享一下我日常使用的扩展,可能大多数扩展大家都已经在使用了,不过也难免有一两个是你不知道的. ...
- IDEA实现SpringBoot热部署
1.pom.xml添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifac ...
- 《The Boost C++ Libraries》 第一章 智能指针
Boost.SmartPointers中提供了多种智能指针,它们采用在智能指针析构时释放内存的方式,帮助管理动态分配的对象.由于析构函数在智能指针生命周期结束时被执行,所以由它管理的动态分配对象可以保 ...
- (1)PyCharm开发工具安装Flask并创建helloworld程序
一.环境描述 1.操作系统:windows7 2.编程语言:python3.6 下载地址:https://www.python.org/downloads/windows/ 3.虚拟化环境:virtu ...
- egg.js 相关
egg sequelize 建表规范 CREATE TABLE `wx_member` ( `id` ) NOT NULL AUTO_INCREMENT COMMENT 'primary key' ...
- 数据分析入门——pandas之DataFrame多层/多级索引与聚合操作
一.行多层索引 1.隐式创建 在构造函数中给index.colunms等多个数组实现(datafarme与series都可以) df的多级索引创建方法类似: 2.显式创建pd.MultiIndex 其 ...
- Spring cloud微服务安全实战-7-4整合SpringBoot和Prometheus
pom文件里面加两个依赖.让SpringBoot暴露出一些断点. 在actuator的机制上面加一些prometheus的端点,暴露出来给prometheus可以识别的数据, 配置文件配置. 要暴露的 ...
- SSM框架新特性关于用Java配置类完全代替XML
项目目录结构 从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法, 这些方法将会被AnnotationConf ...