一 公平锁和非公平锁
公平锁:多个线程按照申请锁的顺序来获取锁
非公平锁:多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取到锁,这就是造成优先级反转或者锁饥饿现象。
在JAVA中,ReentrantLock可通过构造函数至指定是否是公平锁,默认是非公平锁
synchronized默认是非公平锁并且不能变为公平锁
二 独享锁和共享锁
独享锁:一个锁只能被一个线程所持有
共享锁:一个锁可被多个线程持有
在JAVA中?ReentrantLock是独享锁
ReentrantLock中 读锁是共享锁,写锁是独享锁,读写,写读,写写是互斥的
synchronzied方法是独享锁
三 互斥锁和读写锁
互斥锁和读写锁是共享锁和独享锁的具体表现。
四 乐观锁和悲观锁
不是具体的锁,是指看待并发同步的角度
悲观锁:对于同一数据的并发数据,悲观锁认为这时一定会修改数据的,因此会采取加锁的方式实现同步。
乐观锁:对于同一数据的并发操作,乐观锁认为这时不一定会修改数据,因此在更新数据时,会采取不断尝试更新的操作。
在JAVA中 悲观锁是指利用各种锁机制,而乐观锁是指无锁编程,如CAS算法,典型的原子类,通过CAS算法实现原子类操作的更新。
五 分段锁
不是指具体的一种锁,而是一种锁的设计。
分段锁的设计目的就是细化锁的操作,例如当操作不需要更新整个数组时,仅针对数组中的一个元素更新时,我们仅给元素加锁即可。
ConcurrentHashMap就是利用分段锁的形式实现并发操作
和HashMap一样,有一共Entry数组,数组中的每一个元素是一个链表,也是一个Segment(分段锁)
当需要put元素时,不是先对整个HashMap加锁(线程安全的HashTable是整个加锁),而是通过hashcode知道它要放在哪一个分段中,然后对这个分段进行加锁,所以当有多个线程put时,只要不是放在同一个分段中,就不会产生同步阻塞现象。
六 偏向锁,轻量级锁,重量级锁
在JAVA5中,可以通过锁升级机制实现高效地synchronized方法,这三种锁是指synchronized锁的状态,通过对象监视器在对象头的字段来表明。
偏向锁:指一段同步代码一直被一个线程访问,那么该线程就会自动获取这个锁,以降低获取锁的代价。
轻量级锁:当前锁是偏向锁并且被另外一个线程访问时,偏向锁就会升级为轻量级锁,其他线程会通过自旋的方式尝试获取锁,不会阻塞其他线程。
重量级锁:当前锁是轻量级锁,另一个线程自旋到一定次数还没获取到锁,轻量级锁就会升级重量级锁,会阻塞其他线程。
七 自旋锁
指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁。
八 可重入锁(递归锁)
指在同一线程在外层方法获取锁的时候,进入内层方法时会自动获取锁。