setRealData用于去加载真实的数据,加载完毕之后就把isReady设置为true,然后调用notify方法通知正在等待的线程。此时,get方法收到通知就继续执行,然后返回真实数据realData.get().
另外也简单的实现了一个取消任务的方法cancel,去中断正在执行子任务的线程。
4)FutureClient客户端用于发起请求,异步执行任务。
public class FutureClient { public Data call(){ //创建一个代理对象FutureData,先返回给客户端(无论是否有值) final FutureData futureData = new FutureData(); //启动一个新的线程,去异步加载真实的对象 new Thread(new Runnable() { @Override public void run() { //此处注意需要记录一下异步加载真实数据的线程,以便后续可以取消任务。 futureData.setRunningThread(); RealData realData = new RealData(); //等真实数据处理完毕之后,把结果赋值给代理对象 futureData.setRealData(realData); } }).start(); return futureData; } }5)测试
public class Main { static class Chuju{ } static class Shicai{ } public static void main(String[] args) throws InterruptedException { FutureClient fc = new FutureClient(); Data data = fc.call(); Thread.sleep(2000); Shicai shicai = new Shicai(); System.out.println("第二步:食材到位"); if(!data.isDone()){ System.out.println("第三步:厨具还没到,请等待或者取消"); //② // data.cancel(); // System.out.println("已取消"); // return; } //真正需要数据的时候,再去获取 Chuju chuju = (Chuju)data.get(); System.out.println("第三步:厨具到位,可以烹饪了"); cook(chuju,shicai); } public static void cook (Chuju chuju, Shicai shicai){ System.out.println("最后:烹饪中..."); } }执行结果和用JDK提供的Future模式是一模一样的。我们也可以把②出的代码打开,测试任务取消的结果。
第一步:下单 第一步:等待送货 第二步:食材到位 第三步:厨具还没到,请等待或者取消 已取消 被中断:java.lang.InterruptedException: sleep interrupted执行取消之后,执行RealData的子线程就会被中断,然后结束任务。