LongAdder
在AtmoicLong中,多个线程对变量进行CAS操作的话,每次自旋只有一次线程能修改成功,在并发量高的条件下,效率还是有些不够。为了提高性能,LongAdder将一个变量拆分成多个Cell,每个Cell都有一个Long变量,在并发量大的时候,不同的线程先将变量的计算分摊到多个Cell上,将所有Cell的值加起来就是最终的值。
LongAdder只保证了最终一致性
因为在对Cell求和的时候是没有上锁的,所以有可能求和时有别的线程对Cell中的值进行修改,求和得出的结果并不是实时一致的,所以求和的操作只能保证最后是一致的,也就是最终一致性。
伪共享问题
每个CPU内部有自己的缓存,缓存与主存进行数据交换的基本单位是缓存行。当两个线程读取了相同的缓存行后,一个线程修改了缓存行中的一个数据会导致另一个CPU对应的缓存行失效,没有被修改的数据本来是共享的状态却跟着失效了。
缓存行填充
运用缓存行填充技术可以解决伪共享问题,通过缓存行填充,在变量后面将整个缓存行填充,使一个缓存行中只有一个变量,不会因为一个数据修改了导致其他缓存数据失效。
在JDK8中,使用@sun.misc.Contended注解可以实现缓存行填充。LongAdder中的Cell也是这样优化的。