多线程------Future异步任务

简介: 多线程------Future异步任务



前言

Future 是 Java 中用于表示异步计算结果的接口,它允许你在一个线程中开启一个任务,然后在另一个线程中获取计算结果。Future 接口提供了一种在任务执行完成之后获取结果的机制,它允许异步地等待任务完成。

以下是关于 Future 的详细讲解:

1. Future 接口

Future 接口定义了与异步计算结果相关的一系列方法,其中最重要的是:

  • get(): 获取计算结果,如果计算尚未完成,则阻塞直到计算完成。
  • get(long timeout, TimeUnit unit): 获取计算结果,但是最多等待指定的时间。
  • isDone(): 判断计算是否完成。
  • cancel(boolean mayInterruptIfRunning): 尝试取消任务的执行。

2. FutureTask

FutureTaskFuture 接口的一个实现,同时也是 Runnable 接口的实现。你可以把 FutureTask 提交给 Executor 来执行,并在需要的时候通过 Future 来获取计算结果。

import java.util.concurrent.*;
public class FutureTaskExample {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        Callable<Integer> callable = () -> {
            // 模拟一个耗时的任务
            Thread.sleep(2000);
            return 42;
        };
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        // 创建并启动线程
        new Thread(futureTask).start();
        // 在主线程中继续执行其他任务
        System.out.println("Do something else while waiting for the result...");
        // 获取计算结果,会阻塞直到任务完成
        Integer result = futureTask.get();
        // 打印计算结果
        System.out.println("Result: " + result);
    }
}

3. ExecutorServicesubmit() 方法

更常见的做法是使用 ExecutorService 来执行 CallableRunnable,并返回一个 Future 对象。

import java.util.concurrent.*;
public class ExecutorServiceExample {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        Callable<Integer> callable = () -> {
            // 模拟一个耗时的任务
            Thread.sleep(2000);
            return 42;
        };
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        
        // 提交任务并获取 Future 对象
        Future<Integer> future = executorService.submit(callable);
        // 在主线程中继续执行其他任务
        System.out.println("Do something else while waiting for the result...");
        // 获取计算结果,会阻塞直到任务完成
        Integer result = future.get();
        // 打印计算结果
        System.out.println("Result: " + result);
        // 关闭线程池
        executorService.shutdown();
    }
}

 

4. 异常处理

在使用 Future 的时候,需要注意任务可能会抛出异常。你可以使用 try-catch 块来捕获异常。

try {
    Integer result = future.get();
    System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}

5. 超时处理

如果你不想一直等待任务完成,可以使用带有超时参数的 get 方法。

try {
    Integer result = future.get(1, TimeUnit.SECONDS);
    System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
    e.printStackTrace();
}

这样,如果任务在指定时间内没有完成,将抛出 TimeoutException

Future 是在 Java 5 中引入的,它为异步编程提供了一种相对简单的方式。然而,随着时间的推移,Java 的并发编程模型已经进一步发展,现在也有其他更高级的并发工具,例如 CompletableFuture。如果你在新的项目中使用异步编程,可能会考虑使用这些更先进的工具。


相关文章
|
1月前
|
数据采集 存储 Java
「多线程大杀器」Python并发编程利器:ThreadPoolExecutor,让你一次性轻松开启多个线程,秒杀大量任务!
「多线程大杀器」Python并发编程利器:ThreadPoolExecutor,让你一次性轻松开启多个线程,秒杀大量任务!
|
30天前
|
Python
Python学习之路 02 之分支结构
Python学习之路 02 之分支结构
47 0
Python学习之路 02 之分支结构
|
30天前
|
Java Python 开发者
Python 学习之路 01基础入门---【Python安装,Python程序基本组成】
线程池详解与异步任务编排使用案例-xian-cheng-chi-xiang-jie-yu-yi-bu-ren-wu-bian-pai-shi-yong-an-li
78 2
Python 学习之路 01基础入门---【Python安装,Python程序基本组成】
|
1月前
|
存储 算法 Java
【C/C++ 线程池设计思路】 深入探索线程池设计:任务历史记录的高效管理策略
【C/C++ 线程池设计思路】 深入探索线程池设计:任务历史记录的高效管理策略
74 0
|
21天前
|
Java Spring
定时任务里面的任务多线程操作
该内容是关于Spring Boot中配置异步任务和定时任务的代码示例。首先通过`@Configuration`和`@EnableAsync`开启异步支持,然后定义线程池,如使用`ThreadPoolExecutor`并设置核心线程数、最大线程数等参数。接着,在需要异步执行的方法上添加`@Async`注解。此外,通过`@EnableScheduling`开启定时任务,并使用`@Scheduled`定义具体任务和执行周期。若需指定多个线程池,可以创建不同的`Executor` bean,并在`@Async`中指定线程池名称。
19 2
|
25天前
|
JavaScript 前端开发
JS 单线程还是多线程,如何显示异步操作
JS 单线程还是多线程,如何显示异步操作
22 2
|
1月前
|
安全 Java 调度
【C/C++ 线程池设计思路 】设计与实现支持优先级任务的C++线程池 简要介绍
【C/C++ 线程池设计思路 】设计与实现支持优先级任务的C++线程池 简要介绍
44 2
|
1月前
|
JavaScript Java API
spring boot使用异步多线程
一文讲清楚spring boot如何结合异步多线程实现文件的导出这类耗时间的操作优化以及常用的场景,了解异步思想
31 0
spring boot使用异步多线程
|
18天前
|
存储 Java 数据库连接
java多线程之线程通信
java多线程之线程通信
|
29天前
|
存储 缓存 NoSQL
Redis单线程已经很快了6.0引入多线程
Redis单线程已经很快了6.0引入多线程
31 3