偏向锁/轻量级锁/重量级锁
偏向锁性能最好,可以避免执行CAS操作.
轻量级锁用自旋和CAS避免了重量级锁带来的线程阻塞和唤醒,性能中等
重量级锁则会把获取不到的锁的线程阻塞,性能最差
(这三种锁特指synchronized锁的状态,通过在对象头中的mark word来表明锁的状态)
偏向锁
如果至始至终对这把锁都不存在竞争,那就没必要上锁,只需打个标记,这是偏向锁的思想.一个对象被初始化后,还没有任何线程来获取他的锁时,那他就是偏向的,当第一个线程来访问他并尝试获取锁的时候,他就将这个线程记录下来,以后如果尝试获取锁的线程恰好是偏向锁的拥有者,就可以直接获得锁.开销小,性能最好.
轻量级锁
JVM开发者发现在很情况下,synchronized中的代码是被多个线程交替执行的,而不是同时执行,也就是并不存在实际的竞争,或者是只有短时间的锁竞争,用CAS就可以解决,这种情况下用完全互斥的重量级锁是没有必要的.轻量级锁是指当锁原来是偏向锁的时候被另外个线程访问,此时就存在竞争,那么偏向锁就会升级为轻量级锁,线程会通过自旋的形式尝试获取锁,而不会陷入阻塞.
重量级锁
重量级锁是互斥锁,他是利用操作系统的同步机制实现的,所以开销较大,当多个线程直接有实际竞争,且锁的竞争时间长的时候,轻量级锁会让其他申请却拿不到锁的线程进入阻塞状态
可重入锁/非可重入锁
可重入锁
指的是线程当已经持有这把锁了能在不释放这把锁的情况下再次获取这把锁
非可重入锁
虽然线程持有这把锁,但是如果想再次获取这把锁必须先释放锁后才能尝试获取
公平锁/非公平锁
公平锁
公平的含义在于如果线程在拿不到这把锁,那么线程就会进入等待开始排队,在等待队列里等待时间长的线程会优先拿到这把锁,先来先得.
非公平锁
他会在一定情况下忽略掉已经在排队的线程,会有插队的现象发生
自旋锁/非自旋锁
自旋锁
自旋锁的理念是如果线程现在拿不到这把锁,并不会直接陷入阻塞或者释放CPU资源,而是开始利用循环,不停的尝试获取锁,这个循环过程被形象的比喻为"自旋",就像是线程在自我旋转
非自旋锁
非自旋锁的理念就是没有自旋的过程,如果拿不到锁就直接放弃,或者进行其他的处理逻辑,例如去排队或者陷入阻塞等
可中断锁/不可中断锁
可中断锁
Reentrant Lock是典型的可中断锁,如使用lockInterruptibly方法在获取锁的过程中,突然不想获取了那么就可以在中断后去做其他事情,不需要一直等到获得锁才离开
不可中断锁
在Java中,synchronized关键字修饰的锁代表的是不可中断锁,一旦线程申请了锁就没有回头路只能等到拿到锁以后才能进行其他的逻辑处理
悲观锁/乐观锁
悲观锁
悲观锁思想悲观,他会认为如果锁不住这个资源别的线程就会来争抢,就会造成数据结果错误,所以悲观锁为了确保结果的正确性会在每次获取并修改数据时,都把数据所住,让其让线程无法访问此数据,这就能保证数据的准确
乐观锁
乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况不会造成冲突,所以在数据进行提交更新的时候才会正式对数据检查是否出错,如果冲突则会返回给用户异常信息,让用户解决如何去做.乐观锁适用于读多写少的场景,这可以提高程序的吞吐量