02.锁粒度的优化

锁粒度的优化

优化锁的粒度是根据实际的代码逻辑来进行判断,分为锁粒度的细化和锁粒度的粗化 2 种优化方式。

锁粒度的细化

举个简单的例子,JDK 自带的工具类 ConcurrentHashMap 就是一个典型的实现场景,它对锁的拆分方式提高了大大提高了它的吞吐量,ConcurrentHashMap 将自身分成若干个段,每一段都是一个子 HashMap。当需要新增一个的时候,并不是对整个对象进行加锁,而是先根据 hashcode 计算该数据应该被加入到哪个段中,然后对该段加锁,默认情况下 ConcurrentHashMap 有 16 个段,因此运气足够好的时候可以接受 16 个线程同时插入,大大提高了吞吐量。

但是减小锁的粒度也带来了新的问题,当锁粒度过于小的时候,获取全局锁消耗的资源也相应增加,以 ConcurrentHashMap 为例,如果它需要获取当前的 size 就需要对每一个段都加锁。

锁粒度的粗化

在一般情况下,为了保证多线程之间的高效并发,会要求线程持有锁的时间尽量短,但是过度的细化会产生大量的申请和释放锁的操作,这对性能的影响也是非常大的。

for(int i = 0; i < 10000; i++) {
  synchronized(this) {
    todo();
  }
}
synchronized(this) {
    for(int i = 0; i < 10000; i++) {
      todo();
    }
}
上一页
下一页