java同步执行多线程任务(for循环里面执行多线程,执行完毕再执行主线程)

需求:for循环里面下载视频,并开启多线程来执行下载任务。
如果不做任何处理,多线程为异步的,怎么样才能让他下载完一个视频再下载下一个呢?

方法一(本人采用):使用 CountDownLatch

// 创建拥有100个线程的线程池
ExecutorService executor = Executors.newFixedThreadPool(100);
// 创建计数器,初始值数量必须等于线程池数量
CountDownLatch latch = new CountDownLatch(100);

for (int i = 0; i < 5; i++) {
    executor.submit(() -> {
        // 子线程处理下载任务
        doDownLoad();
        //线程执行后,计数器减1
        latch.countDown();
    });
}

//这个是关键代码
// 等待所有子线程的任务执行完毕
//。在主线程中,调用 CountDownLatch.await() 方法阻塞等待所有子线程的任务执行完毕,直到计数器减为 0 才继续执行后续代码。
latch.await(); 

// 所有子线程的任务都已经执行完毕,执行主线程的代码
doSomething...;

方法二:使用 ExecutorService

// 创建拥有 100 个线程的线程池
ExecutorService executor = Executors.newFixedThreadPool(100); 

List<Callable<Void>> tasks = new ArrayList<>();
for (int i = 0; i < 100; i++) {
    tasks.add(() -> {
        // 子线程处理任务
        doDownLoad();
        return null;
    });
}

//ExecutorService 中的 invokeAll() 方法可以提交多个 Callable 或 Runnable 任务,并阻塞等待所有任务完成。该方法返回一个 Future 对象列表,可以通过遍历列表获取各个子线程处理任务后的结果。
// 等待所有子线程的任务执行完毕
executor.invokeAll(tasks); 

// 所有子线程的任务都已经执行完毕,执行主线程的代码
doSomething...

方法三:使用 CompletableFuture 的 allOf() 方法

ExecutorService executor = Executors.newFixedThreadPool(100);

List<CompletableFuture<Void>> futures = new ArrayList<>();
for (int i = 0; i < 100; i++) {
    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
        // 子线程处理任务
        doDownLoad();
    }, executor);
    futures.add(future);
}
//allOf() 方法可以用于等待所有 CompletableFuture 对象的计算结果
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

// 所有子线程的任务都已经执行完毕,执行主线程的代码
doSomething...;

方法四:手动

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    5, // corePoolSize
    5, // maximumPoolSize
    0L, TimeUnit.MILLISECONDS, // keepAliveTime, unit
    new LinkedBlockingQueue<Runnable>()); // workQueue

AtomicInteger count = new AtomicInteger(5); // 计数器,初始值为 5

for (int i = 0; i < 5; i++) {
    executor.execute(() -> {
        // 子线程处理任务
         doDownLoad();
        count.decrementAndGet(); // 计数器减 1
    });
}

while (count.get() > 0) {
    Thread.sleep(100); // 等待一段时间,避免空转浪费 CPU 资源
}

// 所有子线程的任务都已经执行完毕,执行主线程的代码
doSomething...;

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容