螺竹编程
发布于 2024-05-17 / 2 阅读
0

Java并发编程/线程池:Future

Future介绍

在Java中,Future是一种异步编程的机制,它可以在一个线程中提交一个任务,并在另一个线程中执行该任务,并返回一个Future对象,通过Future对象可以获取任务的执行结果或取消任务的执行。

Future的主要方法包括:

  • get():获取任务的执行结果,如果任务还没有完成,则阻塞等待。

  • get(long timeout, TimeUnit unit):获取任务的执行结果,如果任务还没有完成,则在指定的时间内等待,如果超时则抛出TimeoutException异常。

  • cancel(boolean mayInterruptIfRunning):取消任务的执行,如果任务已经完成或已经被取消,则返回false。

  • isDone():判断任务是否已经完成。

  • isCancelled():判断任务是否已经被取消。

Future可以用于多种场景,例如在一个线程中提交一个耗时的任务,并在另一个线程中执行该任务,然后获取执行结果。Future可以帮助开发人员更好地控制线程的执行和结果的返回,避免了线程阻塞和等待的问题。

需要注意的是,Future只是一个异步编程的机制,它并不会自动开启一个新的线程来执行任务,如果需要在另一个线程中执行任务,则需要手动创建一个线程或者使用线程池。此外,如果任务的执行时间很长或者不确定,那么使用Future可能会导致资源的浪费和性能的下降,因此在使用Future时需要根据具体的场景进行选择。

Future例子

假设我们需要从一个网站上下载多张图片,每张图片的下载时间不同,我们可以使用Future来实现并发下载,并在所有图片下载完成后进行后续的处理。

下面是一个使用Future的示例代码:

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class DownloadManager {
    private ExecutorService executor;
    private List<Future<Boolean>> downloadTasks;

    public DownloadManager() {
        executor = Executors.newFixedThreadPool(10);
        downloadTasks = new ArrayList<>();
    }

    public void download(List<String> urls) {
        for (String url : urls) {
            Future<Boolean> future = executor.submit(() -> {
                // 下载图片
                downloadImage(url);
                return true;
            });
            downloadTasks.add(future);
        }
    }

    public void awaitDownloadCompletion() {
        for (Future<Boolean> future : downloadTasks) {
            try {
                future.get(); // 阻塞等待图片下载完成
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
        // 下载完成后进行后续处理
        processDownloadedImages();
    }

    private void downloadImage(String url) {
        // 下载图片的实现
    }

    private void processDownloadedImages() {
        // 处理下载完成的图片的实现
    }
}

在上面的示例代码中,我们使用ExecutorService创建了一个固定线程池,同时定义了一个Future类型的列表来保存所有的下载任务。在download方法中,我们迭代传入的所有URL,为每个URL创建一个Callable对象,并将其提交给ExecutorService,将返回的Future对象添加到下载任务列表中。在awaitDownloadCompletion方法中,我们遍历下载任务列表,调用每个Future的get方法来阻塞等待下载完成,并在所有下载任务完成后执行processDownloadedImages方法进行后续处理。

使用Future可以很方便地实现并发下载多张图片,并在所有图片下载完成后进行后续的处理。