Java并发保存大量图片

1. 流程图

flowchart TD
    start(开始)
    saveImages(保存图片)
    createThreads(创建线程池)
    loadImage(加载图片)
    processImage(处理图片)
    saveImage(保存图片)
    end(结束)
    
    start --> saveImages
    saveImages --> createThreads
    createThreads --> loadImage
    loadImage --> processImage
    processImage --> saveImage
    saveImage --> end

2. 步骤

步骤 描述
1. 保存图片 准备要保存的图片路径和文件名
2. 创建线程池 创建一个线程池来并发处理图片
3. 加载图片 使用多线程加载所有图片
4. 处理图片 对加载的图片进行处理
5. 保存图片 将处理后的图片保存到指定路径

3. 代码实现

3.1 保存图片

String imagePath = "path/to/image.jpg";
String savePath = "path/to/save/";

首先,我们需要准备要保存的图片路径和文件名,将其分别赋值给 imagePathsavePath 变量。

3.2 创建线程池

ExecutorService executorService = Executors.newFixedThreadPool(10);

使用 Executors.newFixedThreadPool(int nThreads) 方法创建一个具有固定线程数的线程池。这里我们创建了一个固定大小为 10 的线程池,可以根据实际情况调整线程数。

3.3 加载图片

List<Future<BufferedImage>> futures = new ArrayList<>();
List<String> imagePaths = getImagePaths(); // 获取所有图片路径

for (String imagePath : imagePaths) {
    Future<BufferedImage> future = executorService.submit(() -> {
        // 加载图片的代码
        BufferedImage image = loadImage(imagePath);
        return image;
    });
    futures.add(future);
}

首先,我们需要获取所有要处理的图片路径,可以自定义 getImagePaths() 方法来获取。然后,使用 executorService.submit(Callable<T> task) 方法提交加载图片的任务,并将返回的 Future 对象添加到 futures 列表中。

3.4 处理图片

List<BufferedImage> images = new ArrayList<>();

for (Future<BufferedImage> future : futures) {
    try {
        BufferedImage image = future.get(); // 获取加载完成的图片
        // 处理图片的代码
        BufferedImage processedImage = processImage(image);
        images.add(processedImage);
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
}

遍历 futures 列表,使用 future.get() 方法获取加载完成的图片。然后,对每个图片进行处理,并将处理后的图片添加到 images 列表中。

3.5 保存图片

for (int i = 0; i < images.size(); i++) {
    String saveFilePath = savePath + "image_" + i + ".jpg";
    BufferedImage image = images.get(i);
    // 保存图片的代码
    saveImage(image, saveFilePath);
}

遍历 images 列表,根据索引生成保存文件的路径,并将对应的图片保存到指定路径。

3.6 完整代码

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

import javax.imageio.ImageIO;

public class ImageProcessor {
    public static void main(String[] args) {
        String savePath = "path/to/save/";

        ExecutorService executorService = Executors.newFixedThreadPool(10);

        List<Future<BufferedImage>> futures = new ArrayList<>();
        List<String> imagePaths = getImagePaths();

        for (String imagePath : imagePaths) {
            Future<BufferedImage> future = executorService.submit(() -> {
                BufferedImage image = loadImage(imagePath);
                return image;
            });
            futures.add(future);
        }

        List<BufferedImage> images = new ArrayList<>();

        for (Future<BufferedImage> future : futures) {
            try {
                BufferedImage image = future.get();
                BufferedImage processedImage = processImage(image);
                images.add(processedImage);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }

        for (int i = 0; i < images.size(); i++) {
            String saveFilePath = savePath + "image_" + i + ".jpg";
            BufferedImage image = images.get(i);
            saveImage(image, saveFilePath);
        }

        executorService.shutdown();
    }

    private static List<String>