您好,登录后才能下订单哦!
CAS原理与JDK8的优化是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
CAS-CompareAndSet,是JDK原子变量类AtomicInteger、AtomicLong、AtomicInteger、AtomicBoolean、AtomicReference等实现的基础,例如对于一个共享变量int,就算是简单的自增操作也不是原子性的,多线程同时自增,可能会导致变量的值比预期结果小。但是可以使用AtomicInteger的incrementAndGet() 方法操作变量,这样结果和预期值一样。跟传统的加锁不同,getAndDecrement()方法并没有给代码加锁。代码类似于:
public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return next; } }
底层通过sun.misc.Unsafe的本地方法compareAndSwapInt实现,这个方法是原子的。
乐观锁与悲观锁的区别
性能对比
synchronized是阻塞的,CAS更新是非阻塞的,只是会重试,不会有线程上下文切换开销,对于大部分比较简单的操作,无论是在低并发还是高并发情况下,这种乐观非阻塞方式的性能都要远高于悲观阻塞式方式。
用来实现乐观非阻塞算法,确保当前线程方法体内使用的共享变量不被其他线程改变,CAS广泛运用在非阻塞容器中。
用来实现悲观阻塞式算法,其用在了显式锁的原理实现,如可重入计数中,调用lock()方法时将通过CAS方法将其设为1,调用unlock则设为递减1。如果同时多个线程调用Lock方法那么必然会导致原子修改不成功,保证了锁的机制,排他性。
ABA问题,普通的CAS操作并不是原子的,因为有可能另一个线程改了值但是又改回了值,那么乐观锁的方式是不能保证原子性的,若业务需要规避这种情况那么可以使用AtomicStampedReference的compareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp)
方法,只有值和时间戳都相等的时候才进行原子更新,每次更新都把当前时间修改进原子变量。
JAVA8新增了LongAdder、DoubleAdder对原子变量进行进一步优化,主要是利用了分段CAS的机制,如果不用LongAdder,用AtomicLong的话,在高并发情况下,会产生一直自旋,导致效率不高。他将一个数分成若干个数,CompareAndSet方法的参数只是比较的这若干个数中的一个数,从而降低了自旋的概率,提高了效率。
关于CAS原理与JDK8的优化是什么问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。