[并发编程]异步编程-FutureTask

目录

FutureTask基本介绍

FutureTask继承结构

应用场景

示例代码

示例1:

示例2:

示例3:

总结    


FutureTask基本介绍

       FutureTask 是 Java 并发编程中用于处理异步任务的一个重要类,它实现了 Runnable 和 Future 接口,主要用于异步任务执行结果获取

       FutureTask 通过整合任务执行与结果管理,简化了异步编程模型,适用于需灵活控制任务生命周期及获取结果的场景‌。

FutureTask继承结构

FutureTask → RunnableFuture → Runnable + Future,兼具任务执行和结果管理的双重能力。‌

应用场景

FutureTask 可以用于以下场景:

  • 异步任务执行:可以在后台线程中执行耗时操作,主线程可以继续执行其他任务。
  • 结果获取:可以在任务执行后获取结果,支持任务的取消。
  • 线程池:可以与 ExecutorService 结合使用,管理异步任务。

示例代码

示例1:

基础线程使用

FutureTask<Integer> task = new FutureTask<>(() -> 1+2);
new Thread(task).start();
Integer result = task.get(); // 阻塞获取结果

        FutureTask 可以结合 Callable 或 Runnable 使用。通常情况下,建议使用 Callable 来返回结果。

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

public class FutureTaskExample {

    public static void main(String[] args) {
        // 创建一个 Callable 任务
        Callable<Integer> callableTask = () -> {
            // 模拟长时间的计算
            Thread.sleep(2000);
            return 42; // 返回计算结果
        };

        // 创建 FutureTask
        FutureTask<Integer> futureTask = new FutureTask<>(callableTask);

        // 启动线程来执行 FutureTask
        new Thread(futureTask).start();

        // 主线程可以做其他工作
        System.out.println("主线程正在执行其他操作...");

        try {
            // 获取计算结果,阻塞直到计算完成
            Integer result = futureTask.get();
            System.out.println("计算结果: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

执行结果:

代码说明:

  • Callable:定义了一个可以返回结果的任务。
  • FutureTask:将 Callable 封装为 FutureTask 对象
  • 线程启动:在新线程中执行 FutureTask。
  • 结果获取:通过 futureTask.get() 获取结果,主线程会在此处阻塞,直到任务完成。

示例2:

线程池集成

ExecutorService executor = Executors.newCachedThreadPool();
Future<Integer> future = executor.submit(() -> 1+2);
Integer result = future.get();
ExecutorService executorService = Executors.newCachedThreadPool();
FutureTask<Integer> futureTask = new FutureTask<>(() -> 1+2);
executorService.execute(futureTask);
Integer result = futureTask.get(); 

       通常情况下,FutureTask 不直接使用,而是通过 ExecutorService 来管理。这可以简化线程管理和任务调度。

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

public class FutureTaskWithExecutorService {
    public static void main(String[] args) {
        // 创建一个固定大小的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        // 定义一个 Callable 任务
        Callable<Integer> callableTask = () -> {
            Thread.sleep(2000); // 模拟长时间运行的任务
            return 42;
        };

        // 包装 Callable 任务为 FutureTask
        FutureTask<Integer> futureTask = new FutureTask<>(callableTask);

        // 提交 FutureTask 到 ExecutorService
        executorService.execute(futureTask);

        try {
            // 在任务执行期间可以做其他事情
            System.out.println("执行其他工作...");
            Integer result = futureTask.get(); // 获取任务结果,阻塞直到完成
            System.out.println("结果: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        } finally {
            executorService.shutdown(); // 关闭线程池
        }
    }
}

执行结果:

代码说明:

  • 创建线程池:使用 Executors.newFixedThreadPool(2) 创建一个固定大小的线程池。
  • 定义任务:实现 Callable 接口并定义一个返回整数的任务。
  • 包装任务:将 Callable 任务包装为 FutureTask 对象。
  • 提交任务:使用 executorService.execute(futureTask) 提交 FutureTask 到线程池。
  • 获取结果:调用 futureTask.get() 来获取任务的结果,这会阻塞直到任务完成。
  • 异常处理:捕获可能的异常,处理任务执行中的错误。
  • 关闭线程池:使用 executorService.shutdown() 关闭线程池,避免资源泄漏。

示例3:

       虽然 FutureTask 通常与 Callable 一起使用,但它也可以与 Runnable 一起使用。如果任务不需要返回结果,可以使用 Runnable :

import java.util.concurrent.FutureTask;

public class FutureTaskRunnableExample {
    public static void main(String[] args) {
        Runnable runnableTask = () -> {
            System.out.println("正在执行任务...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println("任务完成!");
        };

        FutureTask<Void> futureTask = new FutureTask<>(runnableTask, null);
        new Thread(futureTask).start();

        try {
            futureTask.get(); // 等待任务完成
            System.out.println("主线程完成!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

执行结果:

总结    

        FutureTask 是 Java 并发编程中的一个重要工具,是一种有效的异步编程工具,用于处理异步任务。适合用于需要并发执行的任务,能够提高程序的性能和响应速度。通过它,可以轻松地在多线程环境中处理耗时操作,同时保持代码的清晰和可维护性。

        FutureTask 通常与 ExecutorService 一起使用,可以高效地管理线程和任务调度。这种组合使得异步编程更加高效和易于管理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值