本质问题在于total += value;它不是原子操作,并行调用的时候它会改变多个线程共享的对象的可变状态,从而导致错误,在使用并行流需要避免这类问题发生!
思考: 什么情况结果正常,但是并行流比顺序流慢的情况呢???
并行流中更新共享变量,如果你加入了同步,很可能会发现线程竞争抵消了并行带来的性能提升!
特别是limit和findFirst等依赖于元素顺序的操作,它们在并行流上执行的代价非常大
对于较小的数据量,选择并行流几乎从来都不是一个好的决定。并行处理少数几个元素的好处还抵不上并行化造成的额外开销。
备注:sort或distinct等操作接受一个流,再生成一个流(中间操作),从流中排序和删除重复项时都需要知道所有集合数据,如果集合数据很大可能会有问题(如果数据大,都放内存,内存不够就会OOM了)。
使用并行流还是顺序流都应该应该测试,以及压测,如果在并行流正常的情况下,效率有提升就选择并行流,如果顺序流快就选择顺序流。
CompletableFuture异步函数式编程 引入CompletableFuture原因 Future模式的缺点Future虽然可以实现获取异步执行结果的需求,但是它没有提供通知的机制,我们无法得知Future什么时候完成。
要么使用阻塞,在future.get()的地方等待future返回的结果,这时又变成同步操作。要么使用isDone()轮询地判断Future是否完成,这样会耗费CPU的资源。
Future 接口的局限性future接口可以构建异步应用,但依然有其局限性。它很难直接表述多个Future 结果之间的依赖性。实际开发中,我们经常需要达成以下目的:
将两个异步计算合并为一个——这两个异步计算之间相互独立,同时第二个又依赖于第
一个的结果。
等待 Future 集合中的所有任务都完成。
仅等待 Future 集合中最快结束的任务完成(有可能因为它们试图通过不同的方式计算同
一个值),并返回它的结果。
通过编程方式完成一个 Future 任务的执行(即以手工设定异步操作结果的方式)。
应对 Future 的完成事件(即当 Future 的完成事件发生时会收到通知,并能使用 Future
计算的结果进行下一步的操作,不只是简单地阻塞等待操作的结果)
新的CompletableFuture将使得这些成为可能。
CompletableFuture提供了四个静态方法用来创建CompletableFuture对象:
方法入参和返回值有所区别。
里面有非常多的方法,返回为CompletableFuture之后可以用链式编程.的形式继续调用,最后调用一个不是返回CompletableFuture的介绍,和流式操作里面的中间操作-终止操作。
日期 /** * 可以使用Instant代替Date * LocalDateTime代替Calendar * DateTimeFormatter代替SimpleDateFormat */ public static void main(String args[]) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime now = LocalDateTime.now(); System.out.println(now.format(formatter)); //10分钟前 String d1 = now.minusMinutes(10).format(formatter); //10分钟后 String d2 = now.plusMinutes(10).format(formatter); System.out.println(d1); System.out.println(d2); LocalDateTime t5 = LocalDateTime.parse("2019-01-01 00:00:00", formatter); System.out.println(t5.format(formatter)); } JVM方面改变去除了永久代(PermGen) 被元空间(Metaspace)代替 配置:-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=80m 代替 -XX:PermSize=10m -XX:MaxPermSize=10m
用Optional取代null Optional对象创建1、 创建空对象
Optional<String> optStr = Optional.empty();上面的示例代码调用empty()方法创建了一个空的Optional对象型。