JAVA基础——Locks系列——总纲

JAVA基础——Locks系列——总纲今天面试的时候被问到 synchronizer 的底层实现 当时脑子里有图但是怎么也说不出来就很绝望 回来一看往年笔记果然还是漏了很多点以及答错的部分 还是对这段的代码理解得不够透彻 写文章梳理一下 并发容器 J U C java util concurrent 存放了所有的并发类 包括并发工具

大家好,我是讯享网,很高兴认识大家。

今天面试的时候被问到synchronizer的底层实现,当时脑子里有图但是怎么也说不出来就很绝望,回来一看往年笔记果然还是漏了很多点以及答错的部分。还是对这段的代码理解得不够透彻,写文章梳理一下。

并发容器J.U.C(java.util.concurrent),存放了所有的并发类,包括并发工具、并发集合,锁等等。

JAVA之所以会有多线程问题,就在于JAVA内存模型(JMM)


讯享网

多线程修改就会触发数据混乱。

解决方法:

1.JMM使用volatile保证部分的可见性,但是volatile的局限性在于只能在一写多读的情况下保证。

2.使用原子操作类(Atomic···)

        这一类就基于CAS机制+自旋

一、AQS

        AbstractQueuedSynchronizer,是并发容器J.U.C(java.util.concurrent)下locks包内的一个抽象类。它实现了一个FIFO(FirstIn、FisrtOut先进先出)的队列以及state(被volatile修饰)变量。底层实现的数据结构是一个双向链表。有两种模式:独占式和共享式

1.

AQS关键工程类截图
AQS关键工程类截图——AbstractOwnableSynchronizer

 2.

AQS关键工程类截图——AbstractQueuedSynchronizer
AQS关键工程类截图——AbstractQueuedSynchronizer

 详细连接:AQS分析(含底层)icon-default.png?t=N7T8http://t.csdn.cn/RUc49

二、CAS

        CAS是compare and swap的缩写,即我们所说的比较交换。cas是一种基于锁的操作,而且是乐观锁。在java中锁分为乐观锁和悲观锁。悲观锁是将资源锁住,等一个之前获得锁的线程释放锁之后,下一个线程才可以访问。而乐观锁采取了一种宽泛的态度,通过设定条件加锁的方式来处理资源,比如通过给记录加version来获取数据,性能较悲观锁有很大的提高。

        只能有一个变量

                解决方案:使用AtomicReferce

        ABA问题:看似没有被改过的值实际上被修改过。比如 i= 1  ->  i=2 -> i=1。

                解决方案:使用 AtomicStampedReference这个类,可以增加时间戳

        CPU开销大

三、synchronizer

四、ReentrantLock

        是基于AQS实现的。在lock()方法中,执行了Sync(抽象类)的lock()方法,而Sync是继承了AQS。且Sync有两个实现子类,一个FairSync(公平锁)一个NonfairSync(非公平锁)。

        1.公平锁

        2.非公平锁

                多了一个属性判断,直接尝试CAS,尝试将state变为1,如果成果就获取资源。如果失败则进行下一步。

第一步:尝试拿锁;第二步:查看addWaiter;第三步:查看acquireQueued

第一步:尝试拿锁(

tryAcquire(int arg);

讯享网

第二步:查看addWaiter。没拿到锁,需要排队;

addWaiter();

第三步:查看acquireQueued。挂起线程以及被唤醒后续步骤。

五、ReentrantReadWeiteLock

六、CountDownLatch

七、Swmphore

小讯
上一篇 2025-02-17 09:12
下一篇 2025-03-10 11:10

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/58129.html