很优雅的Java Future程序设计模式

Java (36) 2024-01-24 12:12

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说很优雅的Java Future程序设计模式,希望能够帮助你!!!。

Future是一种多线程设计模式,它的核心思想是异步调用。对于Future模式来说,它无法立即返回你需要的数据,但是它会返回一个契约,将来你可以凭借这个契约去获取你需要的信息,下面是多业务场景下传统调用以及Future调用模式流程图。

很优雅的Java Future程序设计模式_https://bianchenghao6.com/blog_Java_第1张

一、传统调用模式

Client调用Server,Server要处理耗时的业务逻辑,这时Client处于等待状态,直至Server端处理完成,在这段时间里,Client什么也做不了,一直傻等。

二、Future设计模式

Client调用Server,Server端立即返回一个契约,然后Server端耗时的业务逻辑用一个单独的线程负责,这时Client不会阻塞,可以干它该干的事儿,等Server端处理完成后,会将真实结果返回给Client。

JDK已经内置了Future,下面是一个示例demo。

RealData.java

RealData.java

import java.util.concurrent.Callable;

public class RealData implements Callable<String> {

    private String para;

    public RealData(String para) {
        this.para = para;
    }

    @Override
    public String call() throws Exception {
        // 利用sleep方法来表示非常耗时的业务逻辑
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 10; i++) {
            sb.append(para);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
}

RealData类实现了Callable接口,用于处理比较耗时的业务逻辑,执行完成之后会回调调用方。

FutureTest.java

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class FutureTest {

    public static void main(String args[]) {
        FutureTask<String> future = new FutureTask<>(new RealData("linxinzheng"));
        ExecutorService executor = Executors.newFixedThreadPool(1);
        //在这里开启线程进行RealData的call()执行
        executor.submit(future);
        System.out.println("请求完毕");

        try {
            // 这里仍然可以做额外的数据操作,这里使用sleep代替其他业务逻辑的处理
            Thread.sleep(2000);
            // 如果此时call()方法没有执行完毕,则依然会等待
            System.out.println("数据 = " + future.get());
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            executor.shutdown();
        }
    }
}

FutureTask交由线程池,用于处理RealData类中比较耗时的业务逻辑,executor.submit()后RealData.call()方法开始执行,但主线程这里不会线程阻塞,接下来主线程可以处理别的业务逻辑,我用sleep(2000)代表,最后,future.get()用于获取子线程的返回结果,如果子线程还没有完成,这里会一直阻塞,直至子线程执行完毕。

这就是一个很典型的Future程序设计模式demo。

今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

发表回复