1、公平锁、非公平锁
公平锁 : 多个线程按照申请锁的顺序来获取锁
非公平锁:多个线程获取锁的顺序不会按照申请锁的顺序,获取锁的概率不一样大 Synchronized 关键字是非公平锁 ,非公平锁的优点吞吐量比公平锁大
Java ReentrantLock而言,通过构造函数指定该锁是否是公平锁,默认是非公平锁
2、可重入锁(递归锁)
可重入锁:又叫递归锁,外层加锁后,内层可以继续加锁 synchronized、Reentrant Lock是可重入锁
3、独享锁,共享锁
独享锁只能被一个线程持有,共享锁可以被多个线程持有 ;
Java ReentrantLock而言,其是独享锁。但是对于Lock的另一个实现类ReadWriteLock,其读锁是共享锁,其写锁是独享锁,synchronized是独享锁。
4、互斥锁\读写锁
互斥锁、读写锁就是独享所和共享锁的具体实现。
ReentrantLock 是互斥锁也是独享锁;
readWriteLock 是读写锁,其读锁是共享锁,写锁是独享锁;
读读 可以并发共享
读写、写写,读写、写读互斥
读写锁是可重入锁
读锁是共享锁
写锁是独占锁
读锁在没有写锁的时候被多个线程同时持有,写锁是独占的(排他的),每次只能有一个写线程,但是可以有多个线程并发的读数据。
5、乐观锁\悲观锁
乐观锁:很乐观,每次去拿数据时候认为别人不会修改,不会加锁,在更新的时候会判断在此期间有没有人去更新数据;乐观锁使用CAS方式实现。
悲观锁:很悲观,每次拿数据都认为别人会修改,每次拿数据都会上锁,这样别人想拿到数据,就会阻塞,直到他拿到锁。
6、分段锁
分段锁是一种锁的设计,不是一种锁。CurrentHashMap其并发实现就是通过分段锁的形式来实现。
分段锁的目的是细化锁的粒度,当操作不需要更新整个数组的时候,就仅仅针对数组中的一项进行加锁操作。
7、偏向锁/轻量级锁/重量级锁
偏向锁、轻量级锁和重量级锁是指锁的状态,并且针对synchronized;
偏向锁是一段代码一直被一个线程所访问,那么该线程会自动获取锁,降低获取锁的代价。
轻量级锁是指当锁为偏向锁的时候,被另一线程所访问,偏量级锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,提高性能。
重量级锁是指当锁为轻量级锁时,另一线程虽然是自旋,但自旋不会一直持续下去,当自旋一定次数时,还没有获取到锁,就会进入阻塞,该锁膨胀为重量级锁,重量级锁会让其他申请单的线程进入阻塞,性能降低。
8、自旋锁
自旋锁是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式尝试获取锁,这样的好处是减少上下文切换的消耗,缺点是循环会消耗cpu。