多线程Future模式

本文深入探讨了Future模式在多线程环境中的应用,如何通过Future模式改善线程间的等待效率,实现在等待资源准备的同时执行其他业务逻辑,特别以网络图片下载为例,展示其在实际场景中的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Future模式:对于多线程来说,如果线程A要等待线程B到结果,那么线程A没有必要等待线程B,直到B有结果,可以先拿到一个未来到Future,等B有结果时再取真实值。

核心:去除了主函数等待时间,并使得原本需要等待的时间段可以用于处理其他的业务逻辑。

在多线程中经常举的一个例子就是:网络图片的下载,刚开始是通过模糊的图片来代替最后的图片,等下载图片的线程下载完图片后在替换。而在这个过程中可以做一些其他的事情。

        首先客户端向服务器请求RealSubject,但是这个资源的创建是非常耗时的,怎么办呢?这种情况下,首先返回Client一个FutureSubject,以满足客户端的需求,于此同时呢,Future会通过另外一个Thread 去构造一个真正的资源,资源准备完毕之后,在给future一个通知。如果客户端急于获取这个真正的资源,那么就会阻塞客户端的其他所有线程,等待资源准备完毕。 

 

公共数据接口,FutureData和RealData都要实现。

/**
 * @Description: 公共的data数据结果
 *
 * @Author: mark
 * @Date: 2019/4/8  11:56 PM
 */
public abstract class Data {
    /**
     * method description: 返回线程执行结果
     *
     * @param:
     * @return: String
     */
    public abstract String getRequest();
}
当有线程想要获取到RealData的时候,程序会进行阻塞。等到realData被注入的时候才会使用getRequest方法。
public class FutureData extends Data {

    //读取结果
    private volatile static boolean flag = false;
    private RealData realData;

    public synchronized void setRealData(RealData realData){
        //如果已经获取到结果,直接返回
        if(flag){
            return;
        }
        //否则获取真实结果
        this.realData = realData;
        flag = true;
        notify();
    }

    @Override
    public synchronized String getRequest() {
        while(!flag){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return realData.getRequest();
    }
}
获取真实数据:
public class RealData extends Data {

    private String result;

    //发送请求
    public RealData(String requestData){
        System.out.println("正在使用data:" + requestData + "网络请求数据,耗时操作需要等待.");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("操作完毕,获取结果");
        this.result = "ok";
    }

    @Override
    public String getRequest() {
        return result;
    }
}

FutureClient  客户端:

public class FutureClient {
    public Data request(String reqStr){
        FutureData futureData = new FutureData();
        new Thread(new Runnable() {
            @Override
            public void run() {
                RealData realData = new RealData(reqStr);
                futureData.setRealData(realData);
            }
        }).start();
        return futureData;
    }
}

调用者:

public class Test {
    public static void main(String[] args) {
        FutureClient futureClient = new FutureClient();
        Data request = futureClient.request("reqData");
        System.out.println("请求发送成功");
        System.out.println("主线程执行其他任务");
        String result = request.getRequest();
        System.out.println("result: " + result);
    }
}

调用者请求资源,futureClient.request("reqData"); 完成对数据的准备当要获取资源的时候,request.getRequest() ,如果资源没有准备好flag = false;那么就会阻塞该线程。直到资源获取然后该线程被唤醒。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值