图解源码之java锁的获取和释放(AQS)篇

Posted 开心的鱼a1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图解源码之java锁的获取和释放(AQS)篇相关的知识,希望对你有一定的参考价值。

补充threadLocal内存泄露问题

threadLocal总结:
1.为什么会泄露:,
由于ThreadLocalMap的生命周期跟Thread一样长,在Thread周期内 ,ThreadLocalMap 中key,value对象只增不减,如果都没有手动删除对应key,都会导致内存泄漏,但是jvm提供的一层保障。
2,jvm如何通过弱引用给我们提供了一层保障
设置ThreadLocalMap的key ThreadLocal对象为弱引用,当key不在被引用时,下次gc回收的时候threadlocal将被回收(即threadLocalMap的key被变为null)
当调用threadLocal,的get,set,remove方法时会清除threadLocalMap的key为空的对象,至此key,value都被回收,不会发生内存泄露
3,为什么jvm提供了保障还会出现内存泄露
线程长时间运行,比如在线程池里的线程,ThreadLocalMap 产生了大量key为null,的value对象,而又没有调用get,set,remove方法,以至于没有回收这些对象导致,
故ThreadLocal使用后务必调用remove方法,以防止内存泄露。

 

以独占式不公平锁为例,通过5个线程争夺ReentrantLock的过程,图解ReentrantLock源码实现,了解显示锁的工作流程。

 

 

 

任何时刻拿到锁的只有一个线程,未拿到锁的线程会打包成节点(node),然后将节点通过CAS自旋的方式,从队列尾部放入同步队列中。

 

 

 

增加尾节点为什么要用cas,因为会存在多个线程竞争尾节点。

 

 

 

以上便是线程竞争锁的过程,以及竞争失败之后需要做的全部事情。

 

以上便是线程获取和释放锁的全过程,可用如下流程图进行归纳。

 

 

另外,以上源码均来自jdk1.8,本文章作为梳理思路,仅摘要了关键部分,详细流程请读者跟着思路自行阅读源码,英文过关是阅读的必要技能之一,不然看不懂注释真的很蛋疼。。重要的事情说三遍,英文一定要好!

英文一定要好!英文一定要好!

 

以上是关于图解源码之java锁的获取和释放(AQS)篇的主要内容,如果未能解决你的问题,请参考以下文章

jdk1.8 J.U.C并发源码阅读------AQS之独占锁的获取与释放

jdk1.8 J.U.C并发源码阅读------AQS之共享锁的获取与释放

jdk1.8 J.U.C并发源码阅读------AQS之共享锁的获取与释放

AQS(AbstractQueuedSynchronizer)源码深度解析—共享式获取锁释放锁的原理一万字

AQS(AbstractQueuedSynchronizer)源码深度解析—同步队列以及独占式获取锁释放锁的原理一万字

J.U.C之AQS:同步状态的获取与释放