多线程设计模式之九 Future模式

Future的含义

Future就是将来的意思, 在开辟多线程去执行某个方法,我们是不能获取到改方法的返回值,应为线程和线程之间是相互隔离的,各自有各自的时间线, 线程和线程之间的通信一般都是使用锁来进行同步。所以线程与线程之间的配合少不了锁。

那回到这个模式的含义,试想一下需求,比如A线程去开辟B线程执行某个方法,但是A在某个时刻想获取这个方法的返回值,还有一个问题想一想,一般线程执行在java中都是在run方法中,而且这个run方法是没有返回值,并且方法里面一般都只是局部变量,如果没有发生内存逃逸,一般都会被jvm优化成局部变量。毕竟局部变量随着方法执行结束内存就释放了。

所以我们需要一个全局变量 来接收这个方法的返回值, 那问题来了,如果这个方法还没有被B线程执行结束,此时A线程要找个全局变量? 这时候怎么搞?能怎么搞返回null呗,但是有没有这样的需求A来拿的时候必须要拿到返回值,就算拿不到A线程也可以等,🆗 拿不就是需要进行阻塞了嘛,所以需要用到锁。

呃抽象一下,全局变量是不是需要一个统一的类? 我们切命名他为FutureTask

所以现在是不是关系流程图可以出来了:
在这里插入图片描述

Future

public interface Future<V> {
    V get();
}

Callable

@FunctionalInterface
public interface Callable<T> {
    T call() throws InterruptedException;
}

FutureTask

/**
 * 将来的任务
 * @Author: puhaiguo
 * @Date: 2022-07-12 23:45
 * @Version 1.0
 */
public class FutureTask<V> implements Future<V>, Runnable {

    /*任务是否完成了*/
    private volatile boolean flag;

    /*任务*/
    private Callable<V> callable;

    /*目标返回值*/
    private V target;

    /*目标方法的异常*/
    private Exception exception;

    public FutureTask(Callable<V> callable) {
        this.callable = callable;
    }

    @Override
    public V get() {
        try {
            synchronized (this) {
                while (!flag) {
                    wait();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            return target;
        }
    }

    public  Exception getException() {
        return exception;
    }

    protected synchronized void set(V target) {
        notify();
        this.target = target;
        this.flag = true;
    }

    @Override
    public void run() {
        V res = null;
        try {
            res = callable.call();
        } catch (Exception e) {
            this.exception = e;
        } finally {
            this.flag = true;
            set(res);
        }
    }
}

测试

/**
 *
 * @Author: puhaiguo
 * @Date: 2022-07-13 00:04
 * @Version 1.0
 */
public class Test {
    public static void main(String[] args) throws InterruptedException {
        FutureTask<String> futureTask = new FutureTask<>(
                () -> {
                    TimeUnit.SECONDS.sleep(10);
                    return "my task yeh";
                }
        );

        Thread thread = new Thread(futureTask);
        thread.start();
        TimeUnit.SECONDS.sleep(1);
        thread.interrupt();
        Exception exception = futureTask.getException();
        System.out.println(exception.getMessage());
    }
}

总结

呃,多线程都是离不开同步,用好线程同步机制,设计出奇妙的模式。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值