悲观锁
认为当前线程在使用资源时,一定会有其他线程并发使用该资源,使用资源前直接对资源进行上锁操作,直到资源使用完成才释放锁,以确保线程安全。
Java中的synchronized、ReentrantLock等排他锁都是一种悲观锁思想的实现。
乐观锁
认为当前线程在使用资源时,不会有其他线程并发使用该资源,使用资源过程不对资源进行加锁操作,在更新资源的时候检查资源是否被修改。若资源未被修改则直接更新,若资源已被更新则放弃更新,并根据实际的业务场景采取相应的处理机制。
版本机制和CAS实现是乐观锁的两种实现方案,Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。
自旋锁
自旋锁是一种乐观锁,线程取出资源进行操作,操作后更新资源,在资源更新前检查资源是否被修改。若资源未被修改则直接更新,若资源已被修改则放弃本次更新,重新取出资源进行操作并再次更新资源,如此往复直到成功更新资源。
ABA问题:判断资源是否已被修改时,存在值初始为A,被修改为B后,又被修改为A,此时则需要通过标识位或版本号来标识资源是否被修改过。标识位只能标识是否被修改过,版本号可以标识有多少次操作。
排他锁
排它锁也称作独占锁,只有一个线程能访问资源,不允许其线程同时访问。
共享锁
可以允许有多个线程同时访问资源。常见的有信号量semaphore、读写锁。
读写锁
读锁:是一种共享锁,可以允许多个线程同时读资源,读的时候不允许对资源进行写操作。
写锁:是一种排他锁,只能由一个线程对资源进行读写操作,不允许其他线程同时读。
统一锁
资源A和B被在多线程场景下存在线程1锁定A等待B,线程2锁定B等待A,此时如果把A+B统一成一个锁,则该锁就是将小颗粒的锁合并成一个大颗粒的锁,称之为统一锁。
分段锁
锁定资源时候不对整个资源直接上锁,将资源根据实际场景进行分段,使用某一段资源时只上锁该段的资源。JDK1.7的ConcurrentHashMap就使用了分段锁来实现高效的并发操作,JDK1.8的ConcurrentHashMap新增了红黑树,没有使用分段锁。