入职之后看书比较少,痛定思痛后,准备重读Java经典书目。那就从Java8实战开始研读。在看到并行流时,决定抽出时间来,将多线程部分知识的各个点传成一条线来整理学习一番。此为第一篇。
Java8并行流
Java8提供了并行流的功能,通过parallel方法,将Stream转换为并行操作提交到线程池处理。比如如下代码通过线程池并行消费处理1到100:
IntStream.rangeClosed(1, 100).parallel().forEach(i -> {
System.out.println(LocalDateTime.now() + ":" + i);
try{
Thread.sleep(100);
}catch (InterruptedException e){
}
});
并行流不确保执行顺序,并且因为每次处理耗时1秒,所以可以看到在机器上,数组按照CPU中核的数目为基准输出。
为了测试这种方法的有效性,可以通过这样一个场景来实现:
- 使用20个线程(threadCount)以并行方式总计执行10000次(taskCount)操作。因为单个任务单线程执行需要10毫秒(任务代码如下),也就是每秒吞吐量是100个操作,那20个线程QPS是2000,执行完10000次操作最少耗时5秒。
public void increment(AtomicInteger atomicInteger){
atomicInteger.incrementAndGet();
try {
TimeUnit.MILLISECONDS.sleep(10);
}catch (InterruptedException e){
e.printStackTrace();
}
}
第一种方式是使用线程。直接把任务按照线程数均匀分割,分割到不同的线程执行,使用CountDownLatch来阻塞主线程,直到所有线程都完成操作。这种方式,需要我们自己分割任务:
private int