使用 FutrueTask 和 Callable 实现多线程

x33g5p2x  于2022-03-22 转载在 其他  
字(1.7k)|赞(0)|评价(0)|浏览(166)

一 点睛

要创建一个线程,可以继承自 Thread 类,或者实现 Runnable 接口,但 JUC 还提供了另外一种方式,通过 Callable + FutureTask 创建并使用线程。

1 FutureTask 

Future 是 JDK 提供用于处理多线程环境异步问题的一种模式,而 FutrueTask 就是对 Future 模式的一种实现。下面通过一段对话来理解什么是“Futura 模式”。

老板:“小王,把会议纪要整理好给我。”

小王:“好的,没问题。”

随后,小王立刻开始整理,几分钟后,小王整理好的文件发送给老板。

以上场景,在多线程之中称为“Futura 模式”。当客户端(老板)向服务端(小王)发起一个请求时,服务端会立刻给客户端返回一个结果(好的,没问题。”),但实际任务并没有开始执行。客户端在拿到“假的”响应结果的同时,服务端才会去真正执行任务,并在任务处理完毕后,将真正的结果再返回给客户端(整理好的文件发送给老板。)。

Future 模式的处理流程如下:

Future 模式的最大好处就是客户端在发送出请求后,可以马上得到一个结果(假的结果),而不用一直等待着服务端来处理。

在使用 FutureTask 时,get() 方法就用于返回服务端真正处理后的真实值(RealData)。由于服务端不一定马上能处理完毕,因此在调用 get() 方法时会出现一定时间的阻塞(等待服务端处理完毕)。

2 Callable

Callable 和 Runnable 类似,都是创建线程的上级接口。二者的区别是,在用 Runnable 方式创建线程时,需要重写 run() 方法;而用 Callable 方式创建线程时,需要重写 call() 方法。更重要的是,run() 方法没有返回值,但 call() 方法却有一个类型为泛型的返回值(即 call() 方法的返回值可以是任意类型),而且 FutureTask 的 get() 方法来接收此返回值。此外,get() 方法也是一个闭锁式的阻塞方法,该方法会一直等待,直到 call() 方法执行完毕并且 return 返回值为止。需要注意的是 call() 方法和 run() 方法一样,也是通过 start() 来调用的。

二 应用

1 问题描述

使用 Callable 创建线程计算 1 到 100 的和并返回给 Main 线程的 sum 变量。 

2 代码

package concurrent;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class TestCallable {
    public static void main(String[] args) {
        // 创建一个 Callable 类型的线程对象
        MyCallableThread myThread = new MyCallableThread();
        // 将线程对象包装成 FutureTask 对象,用于接收线程的返回值
        FutureTask<Integer> result = new FutureTask<>(myThread);
        // 运行线程
        new Thread(result).start();
        // 通过 FutureTask 的 get() 接收 myThread 的返回值
        try {
            Integer sum = result.get();// 以闭锁的方式,获取线程的返回值
            System.out.println(sum);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

class MyCallableThread implements Callable<Integer> {
    @Override
    public Integer call() {
        System.out.println("线程运行中...计算1-100之和");
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            sum += i;
        }
        return sum;
    }
}

三 测试

线程运行中...计算1-100之和

5050

相关文章

微信公众号

最新文章

更多