编程过程中锁的优化

减少锁持有时间

notion image

减小锁粒度

将大对象拆成小对象或将整体资源拆分许多部分,然后指定对每个小对象或部分资源加锁,大大增加并行度,降低锁竞争。
例如HashMap的同步实现:
Collections.synchronizedMap(Map<K,V> m),返回SynchronizedMap对象,它是对整个map加锁
public V get(Object key) {   synchronized (mutex) {return m.get(key);} } public V put(K key, V value) {   synchronized (mutex) {return m.put(key, value);} }
而我们的ConcurrentHashMap则是:
– 若干个Segment :Segment<K,V>[] segments – Segment中维护HashEntry<K,V> – put操作时 • 先定位到Segment,锁定一个Segment,执行put

锁分离

根据同步操作的性质,把锁划分为的读锁和写锁,读锁之间不互斥,提高了并发性。
如ReadWriteLock,读多写少的情况,可以提高性能。
notion image

锁粗化

这看起来与思路1有冲突,其实不然。思路1是针对一个线程中只有个别地方需要同步,所以把锁加在同步的语句上而不是更大的范围,减少线程持有锁的时间;
而锁粗化是指:在一个间隔性地需要执行同步语句的线程中,如果在不连续的同步块间频繁加锁解锁是很耗性能的,因此把加锁范围扩大,把这些不连续的同步语句进行一次性加锁解锁。虽然线程持有锁的时间增加了,但是总体来说是优化了的。
notion image