Java并发编程之Future设计模式 (未来设计模式)

所谓的未来设计模式就是不需要线程阻塞,提前把结果反馈给你。在我们日常开发中经常有这样的场景:我们需要等待一个线程返回结果后,根据这个结果才能执行下面的逻辑。

下面的代码就演示了这个场景:

public class SyncInvoker {
    public static void main(String[] args) {
        String result = getResult();
        System.out.println(result);
        System.out.println("---------------");

        System.out.println("-- do other thing --");
    }

    public static String getResult() {

        try {
            Thread.sleep(100000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return "ok";
    }
}

要干别的事情就需要getResult返回结果,就会阻塞很久。所以随之而生的未来设计模式。

为方便理解,我们先从生活中的例子出发:

假如我们上午9点去蛋糕店定做一个蛋糕,交完钱蛋糕店提供一个收据,凭借收据进行蛋糕的领取,店员让你下午3点去拿蛋糕或者你留下一个地址,他给送货上门。
串行:一直等到下午3点拿了蛋糕,再去做其他的事情。
并行wait:三点做好,一点就去在那等着,等到蛋糕做好后,再去做其他的事情。
回调:你在定蛋糕的时候,留下了一个电话或者地址,等到做好后,用收据作为标示,要么电话通知你取,要么按照地址送货上门。
其中:做蛋糕—>FutureTask , CallBack—>具体地址 ,Future—>收据
具体代码演示:

Future 用来代表未来的一个结果
FutureTask 执行的任务逻辑
FutureService 桥接 Future和FutureTask

//去获取结果
public interface Future<T> {
    T get() throws InterruptedException;
}
//获取结果的具体实现
public class AsynFuture<T> implements Future<T> {
    private volatile boolean done = false;
    private T result;
    public void done(T result) {
        synchronized (this) {
            this.result = result;
            this.done = true;
            this.notifyAll();
        }
    }
    //done he get 不一定是同一个线程
    @Override
    public T get() throws InterruptedException {
        synchronized (this) {
            while (!done) {
                this.wait();
            }
        }
        return result;
    }
}
//具体的任务、需要干的活
public interface FutureTask<T> { 
    //真正干活的
    T call();  
}
//用来连接Future和FutureTask
public class FutureService {
  
  	//第一种情况:自己拿
    public <T> Future<T> submit(final FutureTask<T> task) {
        AsynFuture<T> asynFuture = new AsynFuture<>();
        new Thread(() -> {
            T result = task.call();
            asynFuture.done(result);
        }).start();
        return asynFuture;
    }
  
  //第二种:做好了直接回调给我
    public <T> Future<T> submit(final FutureTask<T> task, final Consumer<T> consumer) {
        AsycFuture asycFuture = new AsycFuture();
        new Thread(() -> {
            T result = task.call();
            asycFuture.done(result);
            consumer.accept(result);
        }).start();
        return asycFuture;
    }
}
//测试一下、此时线程没有阻塞、会先去执行 do other thing 
public class SyncInvoker {
    public static void main(String[] args) throws InterruptedException {
      	//测试第一种:自己拿
        FutureService futureService = new FutureService();
        Future submit = futureService.submit(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "--finish--";
        });
        System.out.println("-------");
        System.out.println(" do other thing ");
        Thread.sleep(100);
        System.out.println("---------");
        System.out.println(submit.get());
      
      
        //测试第二种:直接送货上门(输出)
        FutureService futureService = new FutureService();
        futureService.submit(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "--finish--";
        }, System.out::println);

        System.out.println("-------");
        System.out.println(" do other thing ");
        Thread.sleep(100);
        System.out.println("---------");
    }  
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值