多线程的设计模式:Future模式、Master-Worker模式,生产消费者模式

  1. public interface Data {
  2.  
  3. String getRequest();
  4. }

  

  1. public class FutureClient {
  2. public Data request(final String queryStr){
  3. //1 我想要一个代理对象(Data接口的实现类)先返回给发送请求的客户端,告诉他请求已经接收到,可以做其他的事情
  4. final FutureData futureData = new FutureData();
  5. //2 启动一个新的线程,去加载真实的数据,传递给这个代理对象
  6. new Thread(new Runnable() {
  7. @Override
  8. public void run() {
  9. //3 这个新的线程可以去慢慢的加载真实对象,然后传递给代理对象
  10. RealData realData = new RealData(queryStr);
  11. futureData.setRealData(realData);
  12. }
  13. }).start();
  14.  
  15. return futureData;
  16. }
  17. }

  

  1. public class FutureData implements Data{
  2.  
  3. private RealData realData ;
  4.  
  5. private boolean isReady = false;
  6.  
  7. public synchronized void setRealData(RealData realData) {
  8. //如果已经装载完毕了,就直接返回
  9. if(isReady){
  10. return;
  11. }
  12. //如果没装载,进行装载真实对象
  13. this.realData = realData;
  14. isReady = true;
  15. //进行通知
  16. notify();
  17. }
  18.  
  19. @Override
  20. public synchronized String getRequest() {
  21. //如果没装载好 程序就一直处于阻塞状态
  22. while(!isReady){
  23. try {
  24. wait();
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. //装载好直接获取数据即可
  30. return this.realData.getRequest();
  31. }
  32. }

  

  1. public class RealData implements Data{
  2.  
  3. private String result ;
  4.  
  5. public RealData (String queryStr){
  6. System.out.println("根据" + queryStr + "进行查询,这是一个很耗时的操作..");
  7. try {
  8. Thread.sleep(5000);
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. System.out.println("操作完毕,获取结果");
  13. result = "查询结果";
  14. }
  15.  
  16. @Override
  17. public String getRequest() {
  18. return result;
  19. }
  20. }

  

  1. public class Main {
  2. public static void main(String[] args) throws InterruptedException {
  3.  
  4. FutureClient fc = new FutureClient();
  5. Data data = fc.request("请求参数");
  6. System.out.println("请求发送成功!");
  7. System.out.println("做其他的事情...");
  8.  
  9. String result = data.getRequest();
  10. System.out.println(result);
  11. }
  12. }

  

  1. import java.util.HashMap;
  2. import java.util.Map;
  3. import java.util.concurrent.ConcurrentHashMap;
  4. import java.util.concurrent.ConcurrentLinkedQueue;
  5.  
  6. public class Master {
  7. //1 有一个盛放任务的容器
  8. private ConcurrentLinkedQueue<Task> workQueue=new ConcurrentLinkedQueue<Task>();
  9.  
  10. //2 需要有一个盛放worker的集合
  11. private HashMap<String,Thread> workers =new HashMap<String, Thread>();
  12.  
  13. //3 需要有一个盛放每一个worker执行任务的结果集合
  14. private ConcurrentHashMap<String,Object> resultMap=new ConcurrentHashMap<String, Object>();
  15.  
  16. //4 构造方法
  17. public Master(Worker worker,int workerCount){
  18. worker.setWorkQueue(this.workQueue);
  19. worker.setResultMap(this.resultMap);
  20. for(int i = 0; i < workerCount; i ++){
  21. this.workers.put(Integer.toString(i), new Thread(worker));
  22. }
  23. }
  24. //5 需要一个提交任务的方法
  25. public void submit(Task task) {
  26. this.workQueue.add(task);
  27. }
  28. //6 需要有一个执行的方法,启动所有的worker方法去执行任务
  29. public void execute(){
  30. for(Map.Entry<String,Thread> me: workers.entrySet()){
  31. me.getValue().start();
  32. }
  33. }
  34. //7 判断是否运行结束的方法
  35. public boolean isComplete() {
  36. for(Map.Entry<String, Thread> me : workers.entrySet()){
  37. if(me.getValue().getState() != Thread.State.TERMINATED){
  38. return false;
  39. }
  40. }
  41. return true;
  42. }
  43.  
  44. //8 计算结果方法
  45. public int getResult() {
  46. int priceResult = 0;
  47. for(Map.Entry<String, Object> me : resultMap.entrySet()){
  48. priceResult += (Integer)me.getValue();
  49. }
  50. return priceResult;
  51. }
  52. }

  

  1. import java.util.concurrent.ConcurrentHashMap;
  2. import java.util.concurrent.ConcurrentLinkedQueue;
  3.  
  4. public class Worker implements Runnable{
  5. private ConcurrentLinkedQueue<Task> workQueue;
  6. private ConcurrentHashMap<String,Object> resultMap;
  7. public void setWorkQueue(ConcurrentLinkedQueue<Task> workQueue) {
  8. this.workQueue=workQueue;
  9. }
  10. public void setResultMap(ConcurrentHashMap<String,Object> resultMap){
  11. this.resultMap=resultMap;
  12. }
  13. @Override
  14. public void run(){
  15. while (true){
  16. Task input=this.workQueue.poll();
  17. if(input==null) break;
  18. Object output=handle(input);
  19. this.resultMap.put(Integer.toString(input.getId()),output);
  20. }
  21. }
  22. private Object handle(Task input){
  23. Object output=null;
  24. try {
  25. //处理任务的耗时。。 比如说进行操作数据库。。。
  26. Thread.sleep(500);
  27. output = input.getPrice();
  28. } catch (InterruptedException e) {
  29. e.printStackTrace();
  30. }
  31. return output;
  32. }
  33. }

  

  1. public class Task {
  2. private int id;
  3. private int price ;
  4. public int getId() {
  5. return id;
  6. }
  7. public void setId(int id) {
  8. this.id = id;
  9. }
  10. public int getPrice() {
  11. return price;
  12. }
  13. public void setPrice(int price) {
  14. this.price = price;
  15. }
  16. }

  

  1. import java.util.Random;
  2.  
  3. public class Main {
  4. public static void main(String[] args) {
  5. Master master = new Master(new Worker(), 20);
  6.  
  7. Random r = new Random();
  8. for (int i = 1; i <= 100; i++) {
  9. Task t = new Task();
  10. t.setId(i);
  11. t.setPrice(r.nextInt(1000));
  12. master.submit(t);
  13. }
  14. master.execute();
  15. long start = System.currentTimeMillis();
  16.  
  17. while (true) {
  18. if (master.isComplete()) {
  19. long end = System.currentTimeMillis() - start;
  20. int priceResult = master.getResult();
  21. System.out.println("最终结果:" + priceResult + ", 执行时间:" + end);
  22. break;
  23. }
  24. }
  25.  
  26. }
  27. }

  

生产者-消费者

  1. public final class Data {
  2. private String id;
  3. private String name;
  4.  
  5. public Data(String id, String name){
  6. this.id = id;
  7. this.name = name;
  8. }
  9.  
  10. public String getId() {
  11. return id;
  12. }
  13.  
  14. public void setId(String id) {
  15. this.id = id;
  16. }
  17.  
  18. public String getName() {
  19. return name;
  20. }
  21.  
  22. public void setName(String name) {
  23. this.name = name;
  24. }
  25.  
  26. @Override
  27. public String toString(){
  28. return "{id: " + id + ", name: " + name + "}";
  29. }
  30. }

  

  1. import java.util.Random;
  2. import java.util.concurrent.BlockingQueue;
  3.  
  4. public class Consumer implements Runnable{
  5. private BlockingQueue<Data> queue;
  6. public Consumer(BlockingQueue queue){
  7. this.queue=queue;
  8. }
  9. //随机对象
  10. private static Random r = new Random();
  11. @Override
  12. public void run() {
  13. while(true){
  14. try {
  15. //获取数据
  16. Data data = this.queue.take();
  17. //进行数据处理。休眠0 - 1000毫秒模拟耗时
  18. Thread.sleep(r.nextInt(1000));
  19. System.out.println("当前消费线程:" + Thread.currentThread().getName() + ", 消费成功,消费数据为id: " + data.getId());
  20. } catch (InterruptedException e) {
  21. e.printStackTrace();
  22. }
  23. }
  24. }
  25. }

  

  1. public class Provider implements Runnable{
  2.  
  3. //共享缓存区
  4. private BlockingQueue<Data> queue;
  5. //多线程间是否启动变量,有强制从主内存中刷新的功能。即时返回线程的状态
  6. private volatile boolean isRunning = true;
  7. //id生成器
  8. private static AtomicInteger count = new AtomicInteger();
  9. //随机对象
  10. private static Random r = new Random();
  11.  
  12. public Provider(BlockingQueue queue){
  13. this.queue = queue;
  14. }
  15.  
  16. @Override
  17. public void run() {
  18. while(isRunning){
  19. try {
  20. //随机休眠0 - 1000 毫秒 表示获取数据(产生数据的耗时)
  21. Thread.sleep(r.nextInt(1000));
  22. //获取的数据进行累计...
  23. int id = count.incrementAndGet();
  24. //比如通过一个getData方法获取了
  25. Data data = new Data(Integer.toString(id), "数据" + id);
  26. System.out.println("当前线程:" + Thread.currentThread().getName() + ", 获取了数据,id为:" + id + ", 进行装载到公共缓冲区中...");
  27. if(!this.queue.offer(data, 2, TimeUnit.SECONDS)){
  28. System.out.println("提交缓冲区数据失败....");
  29. //do something... 比如重新提交
  30. }
  31. } catch (InterruptedException e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. }
  36.  
  37. public void stop(){
  38. this.isRunning = false;
  39. }
  40. }

  

  1. public class Main {
  2.  
  3. public static void main(String[] args) throws Exception {
  4. //内存缓冲区
  5. BlockingQueue<Data> queue = new LinkedBlockingQueue<Data>(10);
  6. //生产者
  7. Provider p1 = new Provider(queue);
  8.  
  9. Provider p2 = new Provider(queue);
  10. Provider p3 = new Provider(queue);
  11. //消费者
  12. Consumer c1 = new Consumer(queue);
  13. Consumer c2 = new Consumer(queue);
  14. Consumer c3 = new Consumer(queue);
  15. //创建线程池运行,这是一个缓存的线程池,可以创建无穷大的线程,没有任务的时候不创建线程。空闲线程存活时间为60s(默认值)
  16.  
  17. ExecutorService cachePool = Executors.newCachedThreadPool();
  18. cachePool.execute(p1);
  19. cachePool.execute(p2);
  20. cachePool.execute(p3);
  21. cachePool.execute(c1);
  22. cachePool.execute(c2);
  23. cachePool.execute(c3);
  24.  
  25. try {
  26. Thread.sleep(3000);
  27. } catch (InterruptedException e) {
  28. e.printStackTrace();
  29. }
  30. p1.stop();
  31. p2.stop();
  32. p3.stop();
  33. try {
  34. Thread.sleep(2000);
  35. } catch (InterruptedException e) {
  36. e.printStackTrace();
  37. }
  38. // cachePool.shutdown();
  39. // cachePool.shutdownNow();
  40.  
  41. }
  42. }

  

Java线程设计模式(五)的更多相关文章

  1. java 线程(五)线程安全 Lock接口

    package cn.sasa.demo3; import java.util.concurrent.ExecutionException; public class ThreadDemo { pub ...

  2. java线程的五种状态

    五种状态 开始状态(new) 就绪状态(runnable) 运行状态(running) 阻塞状态(blocked) 结束状态(dead) 状态变化 1.线程刚创建时,是new状态 2.线程调用了sta ...

  3. java常用设计模式五:建造者模式

    1.定义 是一种对象构建的设计模式,它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象. 产品类:一般是一个较为复杂的对象,也就是说创建对象的 ...

  4. Java线程的五种状态详解

    状态转换图 1.new状态:通过new关键字创建了Thread或其子类的对象 2.Runnable状态:即就绪状态.可从三种状态到达,new状态的Thread对象调用start()方法,Running ...

  5. 细说进程五种状态的生老病死——双胞胎兄弟Java线程

    java线程的五种状态其实要真正高清,只需要明白计算机操作系统中进程的知识,原理都是相同的. 系统根据PCB结构中的状态值控制进程. 单CPU系统中,任一时刻处于执行状态的进程只有一个. 进程的五种状 ...

  6. java常用设计模式总览

    一.java的设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式. 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组 ...

  7. java线程池与五种常用线程池策略使用与解析

    背景:面试中会要求对5中线程池作分析.所以要熟知线程池的运行细节,如CachedThreadPool会引发oom吗? java线程池与五种常用线程池策略使用与解析 可选择的阻塞队列BlockingQu ...

  8. Java线程创建形式 Thread构造详解 多线程中篇(五)

    Thread作为线程的抽象,Thread的实例用于描述线程,对线程的操纵,就是对Thread实例对象的管理与控制. 创建一个线程这个问题,也就转换为如何构造一个正确的Thread对象. 构造方法列表 ...

  9. Java多线程(五)线程的生命周期

    点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...

随机推荐

  1. Noip2019暑期训练2 反思

    经过两次测试,通过深刻的反思,我主要发现了以下易犯错误: 1.做题目时过于追求速度,导致好几处代码都出现手误打错的现象!而且,千万不要图快.图方便就复制粘贴,非常容易出错!(例如T3-party中直接 ...

  2. vue使用axios发送请求,都会发送两次请求

    vue 使用axios,每次的请求都会发送两次,第一次的请求头为options CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sha ...

  3. 分享一些好用的 Chrome 扩展

    阅读本文大概需要 2.8 分钟. 前言 使用浏览器扩展程序可以使你的工作效率提高数倍不止,那么下面我就向大家分享一下我日常使用的扩展,可能大多数扩展大家都已经在使用了,不过也难免有一两个是你不知道的. ...

  4. IDEA实现SpringBoot热部署

    1.pom.xml添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifac ...

  5. 《The Boost C++ Libraries》 第一章 智能指针

    Boost.SmartPointers中提供了多种智能指针,它们采用在智能指针析构时释放内存的方式,帮助管理动态分配的对象.由于析构函数在智能指针生命周期结束时被执行,所以由它管理的动态分配对象可以保 ...

  6. (1)PyCharm开发工具安装Flask并创建helloworld程序

    一.环境描述 1.操作系统:windows7 2.编程语言:python3.6 下载地址:https://www.python.org/downloads/windows/ 3.虚拟化环境:virtu ...

  7. egg.js 相关

      egg sequelize 建表规范 CREATE TABLE `wx_member` ( `id` ) NOT NULL AUTO_INCREMENT COMMENT 'primary key' ...

  8. 数据分析入门——pandas之DataFrame多层/多级索引与聚合操作

    一.行多层索引 1.隐式创建 在构造函数中给index.colunms等多个数组实现(datafarme与series都可以) df的多级索引创建方法类似: 2.显式创建pd.MultiIndex 其 ...

  9. Spring cloud微服务安全实战-7-4整合SpringBoot和Prometheus

    pom文件里面加两个依赖.让SpringBoot暴露出一些断点. 在actuator的机制上面加一些prometheus的端点,暴露出来给prometheus可以识别的数据, 配置文件配置. 要暴露的 ...

  10. SSM框架新特性关于用Java配置类完全代替XML

    项目目录结构 从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法, 这些方法将会被AnnotationConf ...