多线程设计模式-未来者设计模式(Future)

未来者设计模式(Future)

实现思路:将提交的任务交给新的线程执行,通过consumer消费者方式,将结果传递给回调方法,不影响主线的执行
优点:执行效率的增加
缺点:异步的方式,如果后面的代码需要结果,无法保证结果到达的事件

使用场景:客户去蛋糕店定制蛋糕,蛋糕店会给客户一个蛋糕券(凭证),客户就回去做自己的事情,蛋糕交给客户有两种方式:

  1. 客户没过一段时间就去问蛋糕店的蛋糕是否做好
  2. 蛋糕店做好后通知给客户去取,或者直接将蛋糕按预留的送货地址上门

定义接口,返回任意类型的结果

package com.ln.concurrent.chapter8;

/**
 * @ProjectName: java-concurrency
 * @Package: com.ln.concurrent.chapter8
 * @Name:FutureTask
 * @Author:linianest
 * @CreateTime:2020/3/25 14:56
 * @version:1.0
 * @Description TODO:定义接口,返回任意类型的结果
 */
public interface Future<T> {
    // 调用者调用的方法
    T get() throws InterruptedException;
}

真正执行任务的接口,与返回者的返回值类型一样

/**
 * @ProjectName: java-concurrency
 * @Package: com.ln.concurrent.chapter8
 * @Name:FutureTask
 * @Author:linianest
 * @CreateTime:2020/3/25 14:56
 * @version:1.0
 * @Description TODO:future 真正执行任务的接口
 */
public interface FutureTask<T> {
    // 线程会掉返回结果的实现
    T call();
}

实现Future接口:异步的方式实现思路

  1. 传参获取执行任务,获取到执行的任务后
  2. 新起一个线程执行任务,并把任务线程方法的线程阻塞住
  3. 当任务执行完成,唤醒任务线程,回调返回方法,获取执行结果
package com.ln.concurrent.chapter8;

/**
 * @ProjectName: java-concurrency
 * @Package: com.ln.concurrent.chapter8
 * @Name:AsynFuture
 * @Author:linianest
 * @CreateTime:2020/3/25 15:04
 * @version:1.0
 * @Description TODO: 异步future实现
 */
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();
        }
    }

    @Override
    public T get() throws InterruptedException {
        synchronized (this) {
            while (!done) {
                this.wait();
            }
        }
        return result;
    }
}

实现连接future接口和future实现的接口

package com.ln.concurrent.chapter8;

import java.util.function.Consumer;

/**
 * @ProjectName: java-concurrency
 * @Package: com.ln.concurrent.chapter8
 * @Name:FutureService
 * @Author:linianest
 * @CreateTime:2020/3/25 15:01
 * @version:1.0
 * @Description TODO: 实现连接future接口和future实现的接口
 */

public class FutureService {
    // todo 被动模式:返回结果后,需要再次调用Future的get方法获取数据
    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;
    }

    // todo 主动模式:任务执行完成后,将结果传递给给指定的方法
    public <T> Future<T> submit(final FutureTask<T> task, final Consumer<T> consumer) {
        AsynFuture<T> asynFuture = new AsynFuture<>();
        new Thread(() -> {
            T result = task.call();
            // done方法时被动模式的,兼容的方式下,留着
//            asynFuture.done(result);
            consumer.accept(result);
        }).start();
        return asynFuture;
    }
}


测试设计模式

package com.ln.concurrent.chapter8;


/**
 * @ClassName:Synclovker
 * @Author:linianest
 * @CreateTime:2020/3/25 14:44
 * @version:1.0
 * @Description TODO: 同步(阻塞)调用
 */

/**
 * Future        -> 代表的是未来的一个凭据
 * FutureTask    -> 将你的调用逻辑进行了隔离
 * FutureService ->桥接Future和FutureTask
 */
public class Synclnvoker {
    public static void main(String[] args) throws InterruptedException {
//        String result = get();
//        System.out.println(result);

        FutureService futureService = new FutureService();
        Future<String> future = futureService.submit(() -> {
            try {
                Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "FINISH";
        }, System.out::println);
        System.out.println("================");
        System.out.println("do other thing.");
        Thread.sleep(1_000L);
        System.out.println("================");

//        System.out.println(future.get());
    }

    public static String get() throws InterruptedException {
        Thread.sleep(10_000L);
        return "FINISH";
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值