java多线程Future设计模式

本文介绍了Java中的Future设计模式,展示了如何通过FutureTask和AsyncFuture实现异步任务的执行。FutureService类作为桥梁,允许调用者线程通过Future对象轮询或者在任务完成后自动接收结果。示例代码中,调用者可以提交任务并选择等待结果或者通过回调函数在任务完成时得到通知。
摘要由CSDN通过智能技术生成
/**
 * Future设计模式
 * 调用者线程A调用任务执行线程B的时候,首先线程B返回一个Future类,然后线程A通过get()方法获取执行结果
 */
@FunctionalInterface
public interface Future<T> {
    /**
     * 返回任务执行线程的执行结果
     *
     * @return 任务执行线程的执行结果
     * @throws InterruptedException 方法异常
     */
    T get() throws InterruptedException;
}

/**
 * Future设计模式
 * 任务执行线程
 */
public interface FutureTask<T> {
    /**
     * 唤起任务
     *
     * @return 执行结果
     */
    T call();
}
//=========================================
/**
 * Future设计模式
 * 任务执行线程返回的 包含任务执行结果的对象
 */
public class AsyncFuture<T> implements Future<T> {
    /**
     * 任务是否执行完成
     */
    private volatile boolean done = false;

    /**
     * 任务执行结果
     */
    private T result;

    /**
     * 设置任务执行完成的结果
     *
     * @param result 任务执行结果
     */
    public synchronized void done(T result) {
        this.result = result;
        this.done = true;
        this.notifyAll();
    }

    @Override
    public T get() throws InterruptedException {
        synchronized (this) {
            // 如果调用get()时任务还未执行完成,则让其wait()等待
            // 此处仍会使调用者线程一直轮询等待
            while (!done) {
                this.wait();
            }
        }
        return result;
    }
}
//===================================
import java.util.function.Consumer;

/**
 * Future设计模式
 * 桥接/组合Future和FutureTask
 * 任务执行线程立即向调用者线程返回凭证
 */
public class FutureService {
    /**
     * 调用者调用任务执行线程,通过凭证轮询任务是否执行完成
     *
     * @param task 任务
     * @return Future凭证
     */
    public <T> Future<T> submit(final FutureTask<T> task) {
        AsyncFuture<T> asyncFuture = new AsyncFuture<>();
        // 唤起执行任务,并将执行结果赋值到Future
        new Thread(() -> {
            T result = task.call();
            asyncFuture.done(result);
        }).start();
        // 返回Future
        return asyncFuture;
    }

    /**
     * 调用者调用任务执行线程,任务执行完成自动通知调用者
     *
     * @param task     任务
     * @param consumer 消费者对象
     * @return Future凭证
     */
    public <T> Future<T> submit(final FutureTask<T> task, final Consumer<T> consumer) {
        AsyncFuture<T> asyncFuture = new AsyncFuture<>();
        // 唤起执行任务,并将执行结果赋值到Future
        new Thread(() -> {
            T result = task.call();
            asyncFuture.done(result);
            consumer.accept(result);
        }).start();
        // 返回Future
        return asyncFuture;
    }
}
//=========================================
/**
 * 异步调用
 */
public class AsyncInvoker {
    public static void main(String[] args) throws InterruptedException {
        /*一、调用者调用任务执行线程,通过凭证轮询任务是否执行完成*/
        /*// 1. 调用者调用任务执行线程,并造成阻塞
        FutureService futureService = new FutureService();
        Future<String> future = futureService.submit(() -> {
            try {
                Thread.sleep(10_000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "FINISH";
        });

        // 2. 调用者线程阻塞,可以执行其他任务
        System.out.println("=====");
        System.out.println("do other thing...");
        Thread.sleep(1000);
        System.out.println("=====");

        // 3. 调用者通过Future获取任务执行结果
        String result = future.get();
        System.out.println(result);*/


        /*二、调用者调用任务执行线程,任务执行完成自动通知调用者*/
        // 1. 调用者调用任务执行线程,并造成阻塞
        FutureService futureService = new FutureService();
        futureService.submit(() -> {
            try {
                Thread.sleep(10_000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "FINISH";
        }, System.out::println);

        // 2. 调用者线程阻塞,可以执行其他任务
        System.out.println("===========");
        System.out.println(" do other thing...");
        Thread.sleep(1000);
        System.out.println("===========");
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值