/**
* Copyright (c) 2018, 2018, tobebetter9527. All rights reserved.
*/
package com.zhiyuan.thread;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
/**
* @Description: 多线程
* @author: tobebetter9527
* @create: 2019-08-31 09:48
*/
public class MultiThread {
private static final Logger LOGGER = LoggerFactory.getLogger(MultiThread.class);
private static final int nThreads = 10;
public static void main(String[] args) {
List<String> names = Lists.newArrayList();
for (int i = 0; i < 101; i++) {
names.add("" + i);
}
parallelSave(names);
}
private static void parallelSave(List<String> names) {
if (CollectionUtils.isEmpty(names)) {
return;
}
/*
* 创建可重复使用固定数量线程的线程池,以共享无界队列方式来运行这些线程,当需要的时候用提供的线程工厂来创建一个新线程.
* 在任意点,大多数线程会处于处理任务的状态。当额外的任务被提交,而所有线程都在活动状态,此时任务将在队列中等待直到有线程可用。
* 假如有线程因为失败等原因被关闭,将创建一个新线程来执行任务。线程将一直存在直到被明确的关闭。
*/
ExecutorService executorService = Executors.newFixedThreadPool(nThreads,
new ThreadFactoryBuilder().setNameFormat("parallelSave - task - %d").build());
// 分割成多少个步骤
int step = names.size() / nThreads + (names.size() % nThreads == 0 ? 0 : 1);
// 允许一个或多个线程等待,直到其他线程完成任务
final CountDownLatch countDownLatch = new CountDownLatch(num);
for (int i = 0; i < names.size(); i += step) {
final int offset = i;
final int end = Math.min(i + step, names.size());
executorService.submit(() -> {
try {
for (int j = offset; j < end; j++) {
System.out.println(names.get(j));
}
} catch (Exception e) {
LOGGER.error("parallelSave.error", e);
} finally {
// 减少latch的数量,当为0是,释放所有等待的线程
countDownLatch.countDown();
}
});
}
try {
// 一个线程或多个线程一直等待,直到其他线程执行的操作完成。
// CountDownLatch用一个给定的计数器来初始化,该计数器的操作是原子操作,
// 即同时只能有一个线程去操作该计数器。调用该类await方法的线程会一直处于阻塞状态,
// 直到其他线程调用countDown方法使当前计数器的值变为零,每次调用countDown计数器的值减1。
// 当计数器值减至零时,所有因调用await()方法而处于等待状态的线程就会继续往下执行
countDownLatch.await();
} catch (InterruptedException e) {
LOGGER.error("parallelSave.多线程等待出现问题", e);
}
executorService.shutdown();
}
}
java开启多线程处理任务的一种方式,ExecutorService,CountDownLatch
于 2019-08-31 11:37:41 首次发布