原文:https://www.jianshu.com/p/46bd98ea9845
公平锁与非公平锁:https://www.cnblogs.com/DDiamondd/p/11316393.html
自旋锁与阻塞锁:
自旋锁:是指当线程获取锁失败的时候,去执行一个无意义的循环,循环结束后再重新去竞争锁,如果竞争不到则继续循环。整个过程中线程一直处于运行(running)状态。
阻塞锁:和自旋锁相对,指当线程获取锁失败时,线程进入阻塞(blocking)状态,当获取相应的信号时(唤醒,时间),进入线程的准备就绪状态,准备就绪状态的所有线程,通过竞争,进入运行状态。
自旋锁的出现原因:线程的阻塞和唤醒需要CPU从用户态转为核心态,频繁的阻塞和唤醒对CPU来说是一件负担很重的工作。而且,很多对象锁的锁定状态只会持续很短的一段时间,例如整数的自加操作,在很短的时间内阻塞并唤醒线程显然不值得,为此引入了自旋锁。
适用情况:自旋等待不能代替阻塞。自旋等待本身虽然,但它是要占用处理器时间的,因此,如果锁被占用的时间很短,自旋当代的效果就会非常好,反之,如果锁被占用的时间很长,那么自旋的线程只会白白浪费处理器资源。
可重入锁和不可重入锁:
可重入锁:指的是同一线程外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。即获取锁的粒度是线程而不是调用。
不可重入锁:和可重入锁相反,指的是同一线程外层函数获得锁之后,不能再次获取该锁。
可重入锁最大的作用是避免死锁。
在JAVA环境下 ReentrantLock(点击查看详解) 和synchronized 都是可重入锁。
类锁和对象锁:
对象锁: synchronized method/block
类锁: static synchronized method/block
在Java程序运行时环境中,JVM需要对两类线程共享的数据进行协调:
1)保存在堆中的实例变量
2)保存在方法区中的类变量
为了实现监视器的排他性监视能力,java虚拟机为每一个对象和类都关联一个锁。代表任何时候只允许一个线程拥有的特权。线程访问实例变量或者类变量不需锁。
类锁实际上用对象锁来实现。当虚拟机装载一个class文件的时候,它就会创建一个java.lang.Class类的实例。当锁住一个对象的时候,实际上锁住的是那个类的Class对象。
乐观锁与悲观锁:https://www.cnblogs.com/DDiamondd/p/11321467.html
共享锁与排他锁:
共享锁:如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排它锁。获准共享锁的事务只能读数据,不能修改数据。
排它锁:如果事务T对数据A加上排它锁后,则其他事务不能再对A加任何类型的锁。获得排它锁的事务即能读数据又能修改数据。
偏向锁 轻量级锁 重量级锁: