Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说很优雅的Java Future程序设计模式,希望能够帮助你!!!。
Future是一种多线程设计模式,它的核心思想是异步调用。对于Future模式来说,它无法立即返回你需要的数据,但是它会返回一个契约,将来你可以凭借这个契约去获取你需要的信息,下面是多业务场景下传统调用以及Future调用模式流程图。
一、传统调用模式
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。
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。