美文网首页
记一次 CompletableFuture 实际使用场景

记一次 CompletableFuture 实际使用场景

作者: smart_dev | 来源:发表于2023-09-08 06:19 被阅读0次

如果忘记使用方法可参考这篇文章

项目背景

  • 在开发短视频下载过程中,发现视频下载时机比较靠后,梳理发现其中有一个原因是我们的普通图片是线性下载的逻辑,即单线程顺序下载。
  • 当所有普通图片下载完毕后才会开始展示到页面。
  • 为此,想优化图片下载的总共时间,一个可以减少用户在页面等待时间,即不能及时浏览下一张图片;另一个也能为视频缓存在提前一定的时机,争取到更多的时间。

那实际问题就转化成了: 如何去开辟多线程(几个为好这里不讨论)同时需要等待结果都回来

优化方案

采用多线程下载静态图片,并且等全部任务执行完毕后,再继续往下执行。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.function.Supplier;

public class ImageDownloadManager {
    private static final String TAG = ImageDownloadManager.class.getSimpleName();
    ExecutorService mExecutor;


    public ImageDownloadManager() {
        mExecutor = ExecutorManager.xxxx();
    }

    public List<PictureItem> download(Context context, List<PictureItem> imageList) {
        List<PictureItem> copyList = new CopyOnWriteArrayList<>(imageList);
        List<CompletableFuture> futureList = new ArrayList<>();
        Log.d(TAG, "Start download for all images.");

        for (PictureItem item : imageList) {
          
                CompletableFuture<Boolean> future = CompletableFuture.supplyAsync(new Supplier<Boolean>() {
                    @Override
                    public Boolean get() {
                        boolean isValid = XXXUtils.preLoadImage(xxxx);
                        if (!isValid) {
                            copyList.remove(item);
                        }
                        Log.d(TAG, "A download end, isValid:" + isValid + " url: " + xxx);
                        return isValid;
                    }
                }, mExecutor);
                futureList.add(future);
            }
        

        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()]));
        voidCompletableFuture.join();
        Log.d(TAG, "End download for all images. download total count = " + futureList.size()
                + " ,download fail count = " + (imageList.size() - copyList.size()));
        return new ArrayList<>(copyList);
    }
}

优化结果

整体优化后速度提升了 100% - 140%

项目方案复用需考虑的因素

  1. 线程个数与任务个数的选择协调
  2. 任务类型,前台还是后台,是否紧急

相关文章

网友评论

      本文标题:记一次 CompletableFuture 实际使用场景

      本文链接:https://www.haomeiwen.com/subject/yuolvdtx.html