Java多线程系列--掌握Future,轻松获取异步任务结果

本文介绍了Java多线程中Future接口的重要性,探讨了Runnable的局限性,并通过实例展示了如何使用FutureTask来处理异步任务的结果。文章还提到了Future模式、Master-Worker模式等多线程业务模式,帮助开发者更好地理解和运用Java并发编程。
摘要由CSDN通过智能技术生成

前言

最近因为一些个人原因,未能抽出太多精力更新Java多线程系列,一搁置就是好几个月,先向读者诸君致歉。

在本系列的其他文章中,已经提到过线程之间的相互协作, 通过分工,将程序系统的不同任务进行线程分离,充分利用机器性能、提升特定线程的利用率和程序的体验感。

详见拙作:Java多线程基础–线程生命周期与线程协作详解.

并在线程池相关文章中提到:作为程序构建者,我们更关心线程(组)的特性和它们所执行的任务,并不愿意分心去做线程操作。

详见拙作:Java多线程基础–线程的创建与线程池管理

然而实际开发中,我们同样关心一个任务对程序系统产生的影响,习惯上称之为任务的的执行结果

Runnable的局限性

在前文中我们谈到,通过编码实现Runnable接口,将获得具有边界性的 “任务”,在指定的线程(或者线程池)中运行。

重新观察该接口,不难发现它并没有方法返回值:

public interface Runnable {
   
    void run();
}

在JDK1.5之前,想利用任务的执行结果,需要小心的操作线程访问临界区资源。使用 回调 进行解耦是非常不错的选择。

练手小Demo – 回顾既往文章知识

注意,为了减少篇幅使用了lambda,但jdk1.5之前并不支持lambda

将计算任务分离到其他线程执行,再回到主线程消费结果

我们将计算、IO等耗时任务丢到其他线程,让主线程专注于自身业务,假想它在接受用户输入以及处理反馈,但我们略去这一部分

我们可以设计出类似下面的代码:

虽然它还有很多不合理之处值得优化,但也足以用于演示

class Demo {
   
    static final Object queueLock = new Object();
    static List<Runnable> mainQueue = new ArrayList<>();
    static boolean running = true;

    static final Runnable FINISH = () -> running = false;

    public static void main(String[] args) {
   
        synchronized (queueLock) {
   
            mainQueue.add(Demo::onStart);
        }
        while (running) {
   
            Runnable runnable = null;
            synchronized (queueLock) {
   
                if (!mainQueue.isEmpty())
                    runnable = mainQueue.remove(0);
            }
            if (runnable != null) {
   
                runnable.run();
            }
            Thread.yield();
        }
    }

    public static void onStart() {
   
        //...
    }

    public static void finish() {
   
        synchronized (queueLock) {
   
            mainQueue.clear();
            mainQueue.add(FINISH);
        }
    }
}

再模拟一个计算的线程和任务回调:

interface Callback {
   
    void onResultCalculated(int result);
}

class CalcThread extends Thread {
   

    private final Callback callback;

    private final int a;

    private final int b;

    public CalcThread(Callback callback, int a, int b) {
   
        this.callback = callback;
        this.a = a;
        this.b = b;
    }

    @Override
    public void run() {
   
        super.run();
        try {
   
            Thread.sleep(10);
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
        final int result = a + b;
        System.out.println("threadId" + Thread.currentThread().getId() + ",calc result:" + result + ";" + System.currentTimeMillis());

        synchronized (queueLock) {
   
            mainQueue.add(() -> callback.onResultCalculated(result));
        }
    }
}

填充一下onStart业务:

class Demo {
   
    public static void onStart() {
   
        System.out.println("threadId" + Thread.currentThread().getId() + ",onStart," + System.currentTimeMillis());

    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值