java使用多线程提升效率
- 应用场景
- 代码实现
- 运行结果
应用场景
循环处理一个列表,每个元素会进行一系列耗时读写操作。使用多线程提升运行速度
List list;
for (Object obj : list) {
long time = System.currentTimeMillis();
obj.doingSomething();
System.out.println(System.currentTimeMillis() - time);
}
代码实现
创建一个线程池
private static final int CORE_POOL_SIZE = 10;
private static final int MAX_POOL_SIZE = 10;
private static final int QUEUE_CAPACITY = 100;
private static final long KEEP_ALIVE_TIME = 1L;
ThreadPoolExecutor executor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(QUEUE_CAPACITY),new ThreadPoolExecutor.CallerRunsPolicy());
将任务均分成数份,分成多少份取决于单个任务的执行时间以及cpu的能力。
//每个线程至少同步30条记录,计算线程数,不超过10个线程
int threadSize = Math.min((int) Math.ceil(list.size() / 30D), MAX_POOL_SIZE);
//计算平均每个任务数
int taskNum = (int) Math.ceil(list.size() / (float) threadSize);
for (int i = 0, size = threadSize - 1; i <= size; i++) {
List<Object> subList= list.subList(i * taskNum, i < size ? (i + 1) * taskNum : list.size());
...
}
使用Future保存每个线程执行结果,在最后轮询每个future状态来同步。
List<Future> taskList = new ArrayList<>();
for (int i = 0, size = threadSize - 1; i <= size; i++) {
List<Object> subList= list.subList(i * taskNum, i < size ? (i + 1) * taskNum : list.size());
taskList.add(executor.submit(() -> {
for (Object obj : list) {
long time = System.currentTimeMillis();
obj.doingSomething();
System.out.println(System.currentTimeMillis() - time);
}
}));
}
for (Future f : taskList) {
while (true) {
if (f.isDone() && !f.isCancelled()) {
break;
}
}
}
运行结果
测试运行1700条记录,每条记录耗时约200ms。
串行共耗时约460s,并行共耗时约60s。效率明显提升