本文共 1118 字,大约阅读时间需要 3 分钟。
悲观锁(Pessimistic Lock)是一种悲观的锁机制,每次访问数据时假定会被其他线程修改,因此在获取数据前对锁进行占位。这种机制在传统关系型数据库中广泛应用,如行锁、表锁等,甚至包括如FOR UPDATE这样的锁定操作。
与之相对,乐观锁(Optimistic Lock)则基于乐观的假设,每次访问数据时假定不会有其他线程修改。在更新数据时,通过版本号等机制检查是否有其他线程进行了修改。这种锁机制通常用于多读场景,能够提升吞吐量。Java中的乐观锁常见实现方式包括版本号和时间戳。
锁的公平性决定了线程获取锁的顺序。公平锁要求线程按照申请顺序获取锁,而非公平锁则允许线程抢占锁,可能导致等待线程饿死。
公平锁的优点是等待线程不会被饿死,但其效率较低。使用ReentrantLock的构造函数new ReentrantLock(true)可以实现公平锁。
非公平锁则以高效率为代价,可能导致部分线程长时间等待。Synchronized、new ReentrantLock()以及new ReentrantLock(false)都可以实现非公平锁。
读写锁允许多个线程同时读取共享数据,但只允许一个线程进行修改。Java中的ReentrantReadWriteLock实现了读写锁,其中ReadLock为读锁(共享锁),WriteLock为写锁(独占锁)。
互斥锁要求一次只能有一个线程持有锁。ReentrantLock和Synchronized都是互斥锁的典型实现。相比Synchronized,ReentrantLock更灵活且面向对象,适用于多种复杂场景。
共享锁允许多个线程同时持有锁并访问共享资源,例如ReadWriteLock。独占锁则要求一次只能有一个线程持有锁,例如ReentrantLock。
这些锁机制都是基于Synchronized实现的,具体细节较为复杂。偏向锁优化了锁的获取效率,适用于单线程场景。轻量级锁在存在锁竞争时通过自旋减少等待时间,而重量级锁则在自旋无效时进行阻塞。
自旋锁是一种优化技术,线程在无法立即获取锁时不会立即阻塞,而是进行自旋操作,减少上下文切换带来的开销。
可重入锁允许线程在获取锁后递归调用同一方法,避免死锁。ReentrantLock实现了可重入锁机制。
可中断锁允许中断线程,通过ReentrantLock的lockInterruptibly()方法实现。中断线程最好的方式是使用共享变量发出信号,线程需周期性检查并有序地中止任务。
转载地址:http://jphfk.baihongyu.com/