Java中的21种锁,图文并茂的详细解释( 三 )


Java中的重量级锁: synchronized
11、轻量级锁 

Java中的21种锁,图文并茂的详细解释

文章插图
 
轻量级锁
轻量级锁是JDK6时加入的一种锁优化机制: 轻量级锁是在无竞争的情况下使用CAS操作去消除同步使用的互斥量 。轻量级是相对于使用操作系统互斥量来实现的重量级锁而言的 。轻量级锁在没有多线程竞争的前提下 , 减少传统的重量级锁使用操作系统互斥量产生的性能消耗 。如果出现两条以上的线程争用同一个锁的情况 , 那轻量级锁将不会有效 , 必须膨胀为重量级锁 。
优点: 如果没有竞争 , 通过CAS操作成功避免了使用互斥量的开销 。
缺点: 如果存在竞争 , 除了互斥量本身的开销外 , 还额外产生了CAS操作的开销 , 因此在有竞争的情况下 , 轻量级锁比传统的重量级锁更慢 。
12、偏向锁偏向锁
偏向锁是JDK6时加入的一种锁优化机制: 在无竞争的情况下把整个同步都消除掉 , 连CAS操作都不去做了 。偏是指偏心 , 它的意思是这个锁会偏向于第一个获得它的线程 , 如果在接下来的执行过程中 , 该锁一直没有被其他的线程获取 , 则持有偏向锁的线程将永远不需要再进行同步 。持有偏向锁的线程以后每次进入这个锁相关的同步块时 , 虚拟机都可以不再进行任何同步操作(例如加锁、解锁及对Mark word的更新操作等) 。
优点: 把整个同步都消除掉 , 连CAS操作都不去做了 , 优于轻量级锁 。
缺点: 如果程序中大多数的锁都总是被多个不同的线程访问 , 那偏向锁就是多余的 。
Java中的21种锁,图文并茂的详细解释

文章插图
 
13、分段锁分段锁
Java中的21种锁,图文并茂的详细解释

文章插图
 
分段锁是一种机制: 最好的例子来说明分段锁是ConcurrentHashMap 。ConcurrentHashMap原理:它内部细分了若干个小的 HashMap , 称之为段(Segment) 。默认情况下一个 ConcurrentHashMap 被进一步细分为 16 个段 , 既就是锁的并发度 。如果需要在 ConcurrentHashMap 添加一项key-value , 并不是将整个 HashMap 加锁 , 而是首先根据 hashcode 得到该key-value应该存放在哪个段中 , 然后对该段加锁 , 并完成 put 操作 。在多线程环境中 , 如果多个线程同时进行put操作 , 只要被加入的key-value不存放在同一个段中 , 则线程间可以做到真正的并行 。
线程安全:ConcurrentHashMap 是一个 Segment 数组 ,  Segment 通过继承ReentrantLock 来进行加锁 , 所以每次需要加锁的操作锁住的是一个 segment , 这样只要保证每个 Segment 是线程安全的 , 也就实现了全局的线程安全
14、互斥锁 
Java中的21种锁,图文并茂的详细解释

文章插图
 
互斥锁
互斥锁与悲观锁、独占锁同义 , 表示某个资源只能被一个线程访问 , 其他线程不能访问 。
  • 读-读互斥
  • 读-写互斥
  • 写-读互斥
  • 写-写互斥
Java中的同步锁: synchronized
15、同步锁 
Java中的21种锁,图文并茂的详细解释

文章插图
 
同步锁
【Java中的21种锁,图文并茂的详细解释】同步锁与互斥锁同义 , 表示并发执行的多个线程 , 在同一时间内只允许一个线程访问共享数据 。
Java中的同步锁: synchronized
16、死锁 
Java中的21种锁,图文并茂的详细解释

文章插图
 
死锁
死锁是一种现象:如线程A持有资源x , 线程B持有资源y , 线程A等待线程B释放资源y , 线程B等待线程A释放资源x , 两个线程都不释放自己持有的资源 , 则两个线程都获取不到对方的资源 , 就会造成死锁 。
Java中的死锁不能自行打破 , 所以线程死锁后 , 线程不能进行响应 。所以一定要注意程序的并发场景 , 避免造成死锁 。
17、锁粗化 
Java中的21种锁,图文并茂的详细解释

文章插图
 


推荐阅读