锁优化

锁优化

在多核时代,多线程对系统的性能提升有着巨大的作用,但是多线程对系统也相应的产生了额外的开销,线程本身的数据、线程的调度、线程的申请释放等都对系统的产生额外的负担,锁是在高并发的环境下为了保证数据的正确性而产生的同步手段,为了进一步提升性能,我们就需要对锁进行优化。

锁的优化思路有:从减小锁的持有时间、锁的粒度的优化、锁分离、锁消除、无锁等等。

锁的代价

现实编程过程中,加锁通常会严重地影响性能。线程会因为竞争不到锁而被挂起,等锁被释放的时候,线程又会被恢复,这个过程中存在着很大的开销,并且通常会有较长时间的中断,因为当一个线程正在等待锁时,它不能做任何其他事情。如果一个线程在持有锁的情况下被延迟执行,例如发生了缺页错误、调度延迟或者其它类似情况,那么所有需要这个锁的线程都无法执行下去。如果被阻塞线程的优先级较高,而持有锁的线程优先级较低,就会发生优先级反转。

Disruptor 论文中讲述了一个实验:这个测试程序调用了一个函数,该函数会对一个 64 位的计数器循环自增 5 亿次;机器环境:2.4G 6 核,运算 64 位的计数器累加 5 亿次。

Method Time (ms)
Single thread 300
Single thread with CAS 5,700
Single thread with lock 10,000
Single thread with volatile write 4,700
Two threads with CAS 30,000
Two threads with lock 224,000

CAS 操作比单线程无锁慢了 1 个数量级;有锁且多线程并发的情况下,速度比单线程无锁慢 3 个数量级。可见无锁速度最快。单线程情况下,不加锁的性能 > CAS 操作的性能 > 加锁的性能。在多线程情况下,为了保证线程安全,必须使用 CAS 或锁,这种情况下,CAS 的性能超过锁的性能,前者大约是后者的 8 倍。