Java 多线程的设计模式之 Future
2017-04-23 18:37
651 查看
Future 设计模式核心原理图:
client端通过 FutureData 发送一个执行耗时操作的请求,FutureData 则直接返回一个回调接口的引用(Data 接口,用于返回获取到的真正结果),然后在 FutureData 内部再另起一个线程去执行真正的耗时操作。当 client 端 执行了获取结果的方法时,如果执行完成,则返回结果。如果还在执行中,则会进入线程等待状态,一直等到执行完成进行线程唤醒之后才能拿到结果。
这个设计模式在 Java JDK 中已经被实现了,这里先看一下自测代码,从最里层开始看:
上面流程图中标注的 RealData 也要实现 Data 接口,这里自己实现的话,其实也是可以省略的,自己写一个获取方法,效果也是一样的。这里模拟的是执行耗时操作。
FutureData 实现类
这里说一下,因为 RealData 的耗时操作直接在构造方法中写的,所以,当进入 setRequest 方法的时候,说明 RealData 已经实例化好了,也就是耗时操作已经执行完成了。这里 FutureData 也就是 RealData 的一个代理,包装着 RealData 的耗时操作过程。
Client 端实现
调用代码
实现代码:
调用方式:
最后说一下线程池的 submit 方法和 execute 方法的区别:
submit 可以传入实现 Callable接口的实例对象。
submit 方法有返回值。
client端通过 FutureData 发送一个执行耗时操作的请求,FutureData 则直接返回一个回调接口的引用(Data 接口,用于返回获取到的真正结果),然后在 FutureData 内部再另起一个线程去执行真正的耗时操作。当 client 端 执行了获取结果的方法时,如果执行完成,则返回结果。如果还在执行中,则会进入线程等待状态,一直等到执行完成进行线程唤醒之后才能拿到结果。
这个设计模式在 Java JDK 中已经被实现了,这里先看一下自测代码,从最里层开始看:
自测 Future 模式实现
RealData 实现类public class RealData { private String data; public RealData(String data) throws InterruptedException { System.out.println("模拟数据加载中。。。"); TimeUnit.SECONDS.sleep(5); this.data = data; } public String getResult() { return data + " - real data"; } }
上面流程图中标注的 RealData 也要实现 Data 接口,这里自己实现的话,其实也是可以省略的,自己写一个获取方法,效果也是一样的。这里模拟的是执行耗时操作。
FutureData 实现类
public class FutureData implements Data { private boolean isReady;// 是否准备好了。 也就是耗时操作是否执行完成了。 private RealData data;// 真实数据操作对象 public synchronized void setRequest(RealData data) { if (isReady) { return; } this.data = data; isReady = true; notify(); } @Override public synchronized String getResult() throws InterruptedException { if (!isReady) { System.out.println("等待数据返回中。。。"); wait(); } return data.getResult(); } }
这里说一下,因为 RealData 的耗时操作直接在构造方法中写的,所以,当进入 setRequest 方法的时候,说明 RealData 已经实例化好了,也就是耗时操作已经执行完成了。这里 FutureData 也就是 RealData 的一个代理,包装着 RealData 的耗时操作过程。
wait() 和 notify() 方法 一定要配合 synchronize 关键字使用。
Client 端实现
public class Client { public Data setRequest(String requestString) { FutureData data = new FutureData(); new Thread(new Runnable() { @Override public void run() { try { System.out.println("client run : " + System.currentTimeMillis()); data.setRequest(new RealData(requestString));// 当 RealData 的构造方法执行完成之后,才会进入到 setRequest的方法中。 } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); return data; } }
调用代码
public class Main { /** * Futrue 设计模式, * client端 发送某个耗时请求 - > FutrueData 代理对象 先返回一个 假对象,然后其内部开启线程进行真实请求操作 -- > RealData 真实处理对象,处理结束之后,回调数据给 代理对象,代理对象再进行通知 client端 */ public static void main(String[] args) throws InterruptedException, ExecutionException { Client client = new Client(); Data data = client.setRequest("this is test"); System.out.println("main : " + System.currentTimeMillis()); System.out.println(data.getResult()); // 会进入线程等待状态。 } }
JDK 内部 Future 实现
上面也说了,这个设计模式 JDK 内部是已经实现了这个机制。 FutureTask 作为我们的代理类,它实现了 Runnable 接口,本身就作为一个独立的线程执行,但是它没有start 方法,必须配合线程池使用。因为 FutureTask 的传入对象是 Callable(接口) 类型,所以,我们的 RealData 类也需要实现 Callable 接口。真实数据最终会通过 Callable 接口的 call() 方法传递给 FutureTask 。实现代码:
public class RealData_1 implements Callable<String> { private String data; public RealData_1(String data) { try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("real data 1"); this.data = data; } @Override public String call() throws Exception { System.out.println("real data 1 call()"); return data; } }
调用方式:
public static void main(String[] args) throws InterruptedException, ExecutionException { // Client client = new Client(); // Data data = client.setRequest("this is test"); // System.out.println("main : " + System.currentTimeMillis()); // System.out.println(data.getResult()); /** * Java jdk 内置 FutureTask 是一个线程类,必须使用配合线程池调用。 */ FutureTask futureTask = new FutureTask(new RealData_1("this is test jdk future")); ExecutorService exe = Executors.newFixedThreadPool(1); exe.submit(futureTask); System.out.println(futureTask.get()); }
最后说一下线程池的 submit 方法和 execute 方法的区别:
submit 可以传入实现 Callable接口的实例对象。
submit 方法有返回值。
相关文章推荐
- 多线程设计模式 - Future模式之JAVA原生实现
- java 多线程设计模式之future
- 别人的Morgan Stanley面试,注重基础,java core、多线程、设计模式、设计程序。。。
- 【JAVA面试题】设计单例模式的多线程实现
- java future设计模式
- Java多线程之并发协作生产者消费者设计模式
- Java多线程之主从设计模式-yellowcong
- Java单例设计模式,多线程下同步
- 多线程设计模式:Future模式
- 设计模式------Java多线程之静态代理模式
- Java多线程Thread-并发协作(生产者消费者设计模式)
- JAVA多线程的设计模式
- Java之多线程中的Future模式
- (一)java多线程编程设计模式之不可变模式
- java多线程中的设计模式
- Java 多线程设计模式
- Java高并发程序设计笔记(八)之Future设计模式
- 多线程设计模式-Future模式
- Java多线程之并发协作生产者消费者设计模式
- 设计模式——单例模式(Java)——考虑多线程环境下的线程安全问题