1.按是否可以重复获取分为 可重入锁、不可重入锁
可重入锁:当前线程获取到锁,当需要再次获取相同锁的时候是可以直接获取的,内部有个计数器,每获取一次计数器+1,释放一次计数器-1,当计数器为0的时候表示当前锁没有人获取
synchronized、ReentrantLock、ReentrantReadWriteLock
不可重入锁:当前线程获取到锁,当需要再次获取相同锁的时候是不可以获取到的,必须要先释放锁,然后在获取锁
ThreadPoolExecutor.worker
2.乐观锁、悲观锁
乐观锁:假设所有线程不会同时操作修改统一数据,乐观锁默认不上锁,CAS就是乐观锁的一种实现,多用于读大于写的场景
Atomic原子类 底层就是CAS
悲观锁:假设所有线程同时操作修改同一数据,操作数据直接上锁。多用于写大于读的场景
synchronized、ReentrantLock、ReentrantReadWriteLock
3.公平锁、非公平锁
公平锁:FIFO队列,先进先出,按照申请锁的顺序分配所,当线程获取锁的时候,如果锁已经被其他线程获取,那么当前线程进入队列末尾,锁被释放,队列头的线程获取锁
非公平锁:不考虑锁的申请顺序,线程会尝试获取锁,如果成功,执行,如果不成功,进入队列,后续其他线程过来继续尝试获取锁
synchronized 是非公平锁
ReentrantLock、ReentrantReadWriteLock 即可以实现公平锁,也可以实现非公平锁
4.互斥锁、共享锁
互斥锁:同一时间点,锁只能被一个线程持有
共享锁:同一时间点,锁可以被多个线程同时持有
synchronized、ReentrantLock 是互斥锁
ReentrantReadWriteLock 既可以互斥也可以共享 因为内部是两把锁,一把读锁,一把写锁,读读共享,读写互斥,写写互斥
5.synchronized
锁消除:synchronized修饰代码如果不存在操作共享资源,则会锁消除,即写了synchronized 和不写一样
锁膨胀:频繁获取和释放锁,触发锁膨胀
锁升级:无锁->偏向锁(jdk15移除)->轻量级锁->重量级锁,锁升级时候当前锁的状态是存放在对象头MarkWord里
synchronized是基于对象锁,锁状态存储在堆中的新建对象的对象头里,其中重量级锁指向ObjectMonitor里存储具体的信息,比如当前获取的线程等信息