JAVA 并发的核心CAS与AQS

JAVA在大型机时代就专注于多线程,火到线程也完全得益于原生多线程的强大。多线程必然带来一个问题,资源的同步问题。java有很多同步手段,但是追根到底就是CAS与AQS

                                                              CAS

CAS就是CompareAndSwap,翻译过来就是:比较与替换,预期值与内存值比较,true就更新新值,false就不进行任何操作,这是个死循环,比较的过程会一直执行。举个例子:


其中flag.compareAndSet(true,false)的返回值为true就是获得到了锁,并且把flag的值置为false,所以内存中的值变为false,下个抢购线程来临时,整个在进行flag.compareAndSet(true,false)时,返回值就变为fasle,返回抢购失败。直到上一个线程把flag把值重新置为fasle,才能抢购成功。

当然,如果抢购非常激烈的话,CAS(本质上是乐观锁)性能不一定比Sync好,说穿了就是占着线程不还,在死循环,避免内核态用户态线程切换导致的性能损耗,但是如果竞争太过激烈,死循环也拿不到执行权,会导致CPU性能的浪费。

                                                      AQS

AQS就是AbstractQueuedSynchronizer,常见的ReentrantLock,Semaphare,CounDownLatch等等同步类,实现都靠他。

AQS实际就三个元素 ,被执行的资源状态,当前执行者,后面排队等着的执行者。

被执行资源状态:要不就是0,要不是1,要不比1大。0的时候代表没线程执行,1的时候说明被执行了,比1大代表被重入了(就是被当前的执行者反复来回的获得执行权)。

当前执行者:就是取得被执行资源的执行权,可重入,除非把资源释放,后面等着的执行者获取不到执行权(需要一直释放到0)

后面的排队等待着:一个双向队列,其中的节点在自旋等待执行权,抄袭一张图(来自https://www.cnblogs.com/waterystone/p/4920797.html)。


这张图基本是对的,最后的成为节点成队头有点问题,实际一旦等待着获得执行权就会弹出双向队列,并不在等待队列中。

你可能感兴趣的:(JAVA 并发的核心CAS与AQS)