乐观锁 & 悲观锁
乐观锁
乐观锁认为一个线程去拿数据的时候不会有其他线程对数据进行更改,所以不会上锁。
实现方式:CAS机制、版本号机制
悲观锁
悲观锁认为一个线程去拿数据时一定会有其他线程对数据进行更改。所以一个线程在拿数据的时候都会顺便加锁,这样别的线程此时想拿这个数据就会阻塞。比如Java里面的synchronized关键字的实现就是悲观锁。
实现方式:就是加锁。
排他锁 & 共享锁
排他锁
该锁一次只能被一个线程所持有。比如synchronized、ReentrantLock
共享锁
该锁可以被多个线程所持有,比如ReentrantReadWriteLock中的读锁ReadLock
独享锁与共享锁通过AQS(AbstractQueuedSynchronizer)来实现的,通过实现不同的方法,来实现独享或者共享。
互斥锁 & 读写锁
互斥锁
互斥锁的具体实现就是synchronized、ReentrantLock。ReentrantLock是JDK1.5的新特性,采用ReentrantLock可以完全替代替换synchronized传统的锁机制,更加灵活。
读写锁
读写锁的具体实现就是读写锁ReadWriteLock。
可重入锁
对于同一个线程在外层方法获取锁的时候,在进入内层方法时也会自动获取锁,可以有效避免死锁。
公平锁 & 非公平锁
公平锁
多个线程相互竞争时要排队,多个线程按照申请锁的顺序来获取锁。
非公平锁
多个线程相互竞争时,先尝试插队,插队失败再排队,比如:synchronized、ReentrantLock
分段锁
分段锁并不是具体的一种锁,只是一种锁的设计。
分段锁的设计目的是细化锁的粒度,当操作不需要更新整个数组的时候,就仅仅针对数组中的一项进行加锁操作。JDK6的ConcurrentHashMap底层就用了分段锁Segment。
偏向锁 & 轻量级锁 & 重量级锁
JDK 1.6 为了减少获得锁和释放锁所带来的性能消耗,在JDK 1.6里引入了4种锁的状态:无锁、偏向锁、轻量级锁和重量级锁,它会随着多线程的竞争情况逐渐升级,但不能降级。