• 多线程集成设计模式--future模式


     多线程开发可以更好的发挥多核cpu性能,常用的多线程设计模式有:Future、Master-Worker、Guard Susperionsion

    一、什么是Future模型:

        该模型是将异步请求和代理模式联合的模型产物。类似商品订单模型。见下图:

     客户端发送一个长时间的请求,服务端不需等待该数据处理完成便立即返回一个伪造的代理数据(相当于商品订单,不是商品本身),用户也无需等待,先去执行其他的若干操作后,再去调用服务器已经完成组装的真实数据。该模型充分利用了等待的时间片段。

    Main:启动系统,调用Client发出请求;

    Client:返回Data对象,理解返回FutureData,并开启ClientThread线程装配RealData;

    Data:返回数据的接口;

    FutureData:Future数据,构造很快,但是是一个虚拟的数据,需要装配RealData;

    RealData:真实数据,构造比较慢。

    注意:

        FutureData是对RealData的包装,是dui真实数据的一个代理,封装了获取真实数据的等待过程。它们都实现了共同的接口,所以,针对客户端程序组是没有区别的;

        客户端在调用的方法中,单独启用一个线程来完成真实数据的组织,这对调用客户端的main函数式封闭的;

        因为咋FutureData中的notifyAll和wait函数,主程序会等待组装完成后再会继续主进程,也就是如果没有组装完成,main函数会一直等待。

    我们来看程序的代码:

    package com.bjsxt.height.design014;
    
    public interface Data {
    
        String getRequest();
    
    }
    package com.bjsxt.height.design014;
    
    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;
        }
    
    }
    package com.bjsxt.height.design014;
    
    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();
        }
    
    
    }
    package com.bjsxt.height.design014;
    
    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;
        }
        
    }
    package com.bjsxt.height.design014;
    
    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);
            
        }
    }

    程序运行的结果是:

    请求发送成功!
    做其他的事情...
    根据请求参数进行查询,这是一个很耗时的操作..
    操作完毕,获取结果
    查询结果

    在主程序中调用

    fc.request("请求参数");//这里会立刻返回,能够做其他事情
    该函数会立刻返回不会阻塞,此时主线程暂时不需要真实的数据,真实的数据还在后头继续加加载。
    这个时候主线程就可以继续做其他的事情,不会导致线程的阻塞。
    当主线程需要使用真实的数据的时候就调用data.getRequest();方法来获得真实的数据,如果数据没有被加载完成,此时主线程要被阻塞,直到数据加载完成,才能继续做后面的事情

    while(!isReady){
    try {
    wait();

    这个设计模式相当的经典呀



  • 相关阅读:
    【洛谷P4887】【模板】莫队二次离线(第十四分块(前体))
    查询数据库表大小
    java程序使用ssl证书连接mysql
    win32- 函数运行速度测试
    回调函数是嘛东西
    win32-读取控制台中所有的字符串
    关于 websocket 的一些学习
    idea下载地址
    ida 重新定义
    P1650 田忌赛马(贪心)
  • 原文地址:https://www.cnblogs.com/kebibuluan/p/7640171.html
Copyright © 2020-2023  润新知