欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java深入学习(4):Future模式

程序员文章站 2022-07-02 12:59:38
Future模式: 其实相当于是前端的Ajax 比如我们使用多线程下载文件时候,每一个线程都会发送HTTP请求资源。而我如何知道,文件下载完毕呢? 也就是说,主线程如何获得子线程的执行结果呢? 创建多线程中的实现runnable接口方式和继承thread类,然后start方法都是直接执行代码的,无法 ......

future模式:

其实相当于是前端的ajax

比如我们使用多线程下载文件时候,每一个线程都会发送http请求资源。而我如何知道,文件下载完毕呢?

也就是说,主线程如何获得子线程的执行结果呢?

创建多线程中的实现runnable接口方式和继承thread类,然后start方法都是直接执行代码的,无法知道执行的结果(主线程无法知道进度)。

 

这里要说的是新方式:使用callable接口和future模式

public class callabletest {
    public static void main(string[] args) throws exception {
        executorservice newcachedthreadpool = executors.newcachedthreadpool();
        future<string> submit = newcachedthreadpool.submit(new taskcallable());
        system.out.println("主线程运行");
        string result = submit.get();
        system.out.println(result);
    }
}

class taskcallable implements callable {
    @override
    public string call() throws exception {
        system.out.println("开始执行任务");
        thread.sleep(3000);
        system.out.println("执行任务结束");
        return "success";
    }
}

打印:

主线程运行
开始执行任务
执行任务结束
success

 

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

 

future模式实例:对于多线程,如果线程a要等待线程b的结果,那么线程a没必要等待b,直到b有结果,可以先拿到一个未来的future,等到b有结果时再取真实的结果

 

自己实现future模式:

/**
 * 公共data数据结果
 */
public abstract class data {
    /**
     * 返回线程的执行结果
     * @return string
     */
    public abstract string getrequest();
}
/**
 * 获取真实数据
 */
public class realdata extends data {

    private string result;

    realdata(string data) {
        system.out.println("正在使用data->" + data + " 进行网络请求");
        try {
            thread.sleep(3000);
        } catch (exception e) {
            e.printstacktrace();
        }
        system.out.println("操作执行完毕");
        this.result = "success";
    }

    @override
    public string getrequest() {
        return result;
    }
}
/**
 * 当有线程要获取realdata的时候
 * 程序会被阻塞
 * 等到realdata被注入才会使用getrequest方法
 */
public class futuredata extends data {
    private boolean flag = false;
    private realdata realdata;

    /**
     * 读取data数据
     */
    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 (exception e) {
                e.printstacktrace();
            }
        }
        return realdata.getrequest();
    }
}
public class futureclient {

    public data submit(string requestdata){
        futuredata futuredata = new futuredata();
        new thread(new runnable() {
            @override
            public void run() {
                realdata realdata = new realdata(requestdata);
                futuredata.setrealdata(realdata);
            }
        }).start();
        return futuredata;
    }
}

测试类:

public class main {
    public static void main(string[] args) {
        futureclient futureclient = new futureclient();
        data request = futureclient.submit("666");
        system.out.println("主线程数据发送成功");
        system.out.println("主线程执行其他任务");
        string result = request.getrequest();
        system.out.println(result);
    }
}

 

打印如下:

主线程数据发送成功
主线程执行其他任务
正在使用data->666 进行网络请求
操作执行完毕
success