1.Stream1.1.允许你声明性地将顺序流转变成并行流1.2.能对这些集合执行操作流水线,可以充分利用计算机的多个核2.并行流2.1.把内容拆分成多个数据块,用不同线程分别处理每个数据块的流2.2.自动地把工作负荷分配到多核处理器的所有核2.3.内部迭代让你可以并行处理一个流,而无须在代码中显式使用和协调不同的线程2.4.对顺序流调用parallel方法,你可以将流转换成并行流2.5.并行流调用sequential方法就可以把它变成顺序流2.6.最后一次parallel或sequential调用会影响整个流水线2.7.内部使用了默认的ForkJoinPool2.7.1.默认的线程数量就是你的处理器数量2.7.2.Runtime.getRuntime().availableProcessors()得到2.7.3.java.util.concurrent.ForkJoinPool.common.parallelism来修改线程池大小3.Java微基准套件3.1.Java microbenchmark harness, JMH3.2.一个以声明方式帮助大家创建简单、可靠微基准测试的工具集3.3.支持Java3.4.支持可以运行在Java虚拟机(Java virtual machine, JVM)上的其他语言3.5.选择适当的数据结构往往比并行化算法更重要3.5.1.LongStream.rangeClosed3.6.并行软件的行为和性能有时是违反直觉的,因此一定要测量,确保你并没有把程序拖得更慢4.并行化的代价4.1.并行化过程本身需要对流做递归划分4.2.把每个子流的归约操作分配到不同的线程4.3.然后把这些操作的结果合并成一个值4.4.多个核之间移动数据的代价也可能比你想的要大4.4.1.保证在核中并行执行工作的时间比在核之间传输数据的时间长4.5.很多情况下不可能或不方便并行化4.5.1.如果结果错了,算得快就毫无意义了5.高效使用并行流5.1.适用于要处理的元素数量庞大,或处理单个元素特别耗时的时候5.2.并行流并不总是比顺序流快5.2.1.用适当的基准来检查其性能5.3.自动装箱和拆箱操作会大大降低性能5.4.有些操作本身在并行流上的性能就比顺序流差5.4.1.limit和findFirst等依赖于元素顺序的操作5.4.2.findAny会比findFirst性能好,因为它不一定要按顺序来执行5.5.调用unordered方法来把有序流变成无序流5.5.1.对无序并行流调用limit可能会比单个有序流(比如数据源是一个List)更高效5.6.流的操作流水线的总计算成本5.6.1.设N是要处理的元素的总数,Q是一个元素通过流水线的大致处理成本,则N*Q就是这个对成本的一个粗略的定性估计5.6.2.Q值较高就意味着使用并行流时性能好的可能性比较大5.7.对于较小的数据量,选择并行流几乎从来都不是一个好的决定5.8.流背后的数据结构是否易于分解5.8.1.ArrayList的拆分效率比LinkedList高得多
5.9.终端操作中合并步骤的代价是大是小6.分支/合并框架6.1.分治算法的并行版本6.2.以递归方式将可以并行的任务拆分成更小的任务,然后将每个子任务的结果合并起来生成整体结果6.3.ExecutorService接口的一个实现,它把子任务分配给线程池(称为ForkJoinPool)中的工作线程6.4.对一个任务调用join方法会阻塞调用方,直到该任务做出结果6.5.不应该在RecursiveTask内部使用ForkJoinPool的invoke方法6.6.应该始终直接调用compute或fork方法,只有顺序代码才应该用invoke来启动并行计算6.7.对子任务调用fork方法可以把它排进ForkJoinPool6.8.工作窃取6.8.1.随机选了一个别的线程,从队列的尾巴上“偷走”一个任务7.Spliterator7.1.一种自动机制来为你拆分流7.2.代表“可分迭代器”(splitable iterator)7.3.用于遍历数据源中的元素,但它是为了并行执行而设计的7.4.特性是通过characteristics方法声明的7.5.Java没有元组(tuple,用来表示由异类元素组成的有序列表的结构,不需要包装对象),所以你必须创建一个新类来把状态封装起来