同步系列,这是彤哥想了很久的名字,原本是准备写锁相关的内容,可是java中的CountDownLatch、Semaphore、CyclicBarrier这些类又不属于锁,它们和锁又有不少共同点,都是为了协同多线程的执行,都是一种同步器,因此这里就借用同步来取名字了,也就是“同步系列”的来源。java
这一篇的内容会比较多,大体包含三大主题:java中的锁、同步器、分布式锁,大体讲的内容以下:sql
(1)volatile数组
(2)synchronized多线程
(3)AQS及Condition并发
(4)ReentrantLock分布式
(5)ReentrantReadWriteLock性能
(6)StampedLock学习
(7)CountDownLatch优化
(8)Semaphore线程
(9)CyclicBarrier
(10)Phaser
(11)Mysql实现分布式锁
(12)Redis实现分布式锁
(13)Zookeeper实现分布锁
这些内容都比较晦涩难懂,网上也有比较多的资料,但每每讲得不够透彻,彤哥会尽可能用通俗易懂的语言把这些问题讲清楚。
关于锁的名词也有不少,彤哥大体整理了下,所有列到这里:
(1)公平锁/非公平锁
公平锁,是指按照线程申请的顺序获取锁。
非公平锁,是指不是按照线程申请的顺序获取锁,有可能后申请的线程反而先获取到锁,假如先来的线程一直获取不到锁,会形成锁饥饿现象。
ReentrantLock中能够经过构造方法指定是否为公平锁,默认为非公平锁,非公平锁的优势在于吞吐量大。
synchronized没法指定为公平锁,一直都是非公平锁。
(2)可重入锁
可重入锁,是指一个线程获取锁以后再尝试获取锁时会自动获取锁,可重入锁的优势是避免死锁。
ReentrantLock和synchronized都是可重入锁。
(3)独享锁/共享锁
独享锁,是指锁一次只能被一个线程持有。
共享锁,是指锁一次能够被多个线程持有。
ReentrantLock和synchronized都是独享锁,ReadWriteLock的读锁是共享锁,写锁是独享锁。
(4)互斥锁/读写锁
与独享锁/共享锁的概念差很少,是独享锁/共享锁的具体实现。
ReentrantLock和synchronized都是互斥锁
ReadWriteLock是读写锁
(5)乐观锁/悲观锁
悲观锁,是指认为对于同一个数据的并发操做必然会发生修改,即便不会发生修改也这么认为,因此必定要加锁。
乐观锁,是指认为对于同一个数据的并发操做不必定会发生修改,在更新数据的时候,尝试去更新数据,若是失败就不断尝试。
悲观锁适用于写操做多的场景,乐观锁适用于读操做多的场景。
(6)分段锁
分段锁,是一种锁的设计思路,它细化了锁的粒度,主要运用在ConcurrentHashMap中,实现高效的并发操做,当操做不须要更新整个数组时,就只锁数组中的一项就能够了。
(7)偏向锁/轻量级锁/重量级锁
这三个锁主要是针对synchronized进行优化使用的,主要是经过对象监视器在对象头中的字段来代表的。
偏向锁,是指一段同步代码一直被一个线程访问,那么这个线程会自动获取锁,下降获取锁的代价。
轻量级锁,是指当锁是偏向锁时,被另外一个线程所访问,偏向锁会升级为轻量级锁,这个线程会经过自旋的方式尝试获取锁,不会阻塞,提升性能。
重量级锁,是指当锁是轻量级锁时,当自旋的线程自旋了必定的次数后,尚未获取到锁,就会进入阻塞状态,该锁升级为重量级锁,重量级锁会使其余线程阻塞,性能下降。
(8)自旋锁
自旋锁,是指尝试获取锁的线程不会阻塞,而是循环的方式不断尝试,这样的好处是减小线程的上下文切换带来的开锁,提升性能,缺点是循环会消耗CPU。
(9)监视器锁
synchronized的实现方式,使用monitorenter和monitorexit来实现。
(10)mutex锁
互斥锁,LockSupport.part()底层是经过mutex实现的。
招募令:
由于彤哥自己工做也比较繁忙,很难作到日更,因此这里诚邀广大好友积极投稿,你们一块儿学习一块儿进步。
可在公众号后台给我留言“投稿”,互加好友详细讨论投稿内容。
固然,其它问题也可在公众号后台留言,不论是生活上、工做上、心理上仍是身体上的,欢迎叨扰,留言必回。
欢迎关注个人公众号“彤哥读源码”,查看更多源码系列文章, 与彤哥一块儿畅游源码的海洋。