在多线程下,对临界资源的访问需要加锁,可以选择互斥锁这样的粗粒度锁或者基于CAS指令的原子语句实现互斥访问。关于CAS等原子操作的概念参见下面的文章:
读写锁工作原理:
- 当「写锁」没有被线程持有时,多个线程能够并发地持有读锁,这大大提高了共享资源的访问效率,因为「读锁」是用于读取共享资源的场景,所以多个线程同时持有读锁也不会破坏共享资源的数据。
- 但是,一旦「写锁」被线程持有后,读线程的获取读锁的操作会被阻塞,而且其他写线程的获取写锁的操作也会被阻塞
所以说,写锁是独占锁,因为任何时刻只能有一个线程持有写锁,类似互斥锁和自旋锁,而读锁是共享锁,因为读锁可以被多个线程同时持有。
知道了读写锁的工作原理后,我们可以发现,读写锁在读多写少的场景,能发挥出优势。
另外,根据实现的不同,读写锁可以分为「读优先锁」和「写优先锁」。
以下代码利用atomic实现了一个轻量级的读写资源锁,相比利用互斥锁实现的读写锁,本锁更类似自旋锁,通过 CPU 提供的 CAS
函数(Compare And Swap),在「用户态」完成加锁和解锁操作,不会主动产生线程上下文切换,所以相比互斥锁来说,会快一些,开销也小一些,并且可以根据需要通过构造函数参数设置读/写优先,且locck/unlock语句允许嵌套
lock.readLock();
lock.readLock();
...
lock.readUnlock();
lock.readUnlock();
也允许在写入状态下嵌套读取,比如
lock.writeLock();
lock.writeLock();
lock.readLock();
...
lock.readUnlock();
lock.writeUnlock();
lock.writeUnlock();