Java并发基础(八)-locks包

本文介绍了Java并发编程中的locks包,包括Condition、LockSupport、ReentrantReadWriteLock、ReentrantLock和StampedLock等核心组件。Condition允许在Lock上创建多个等待集,LockSupport提供线程阻塞和唤醒原语,ReentrantReadWriteLock实现了读写锁,ReentrantLock支持可重入和公平锁,而StampedLock是Java 8引入的高效读写锁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 前言

Java锁的种类 java中的锁种类是真的多。而locks包下也有一些。包结构如下:
这里写图片描述

  • AbstractOwnableSynchronizer 一个线程拥有的同步器,这个类提供了创建锁和相关同步器的基础
  • AbstractQueuedLongSynchronizer 所有的同步状态都是用long变量来维护的,而不是int,在需要64位的属性来表示状态的时候会很有用
  • AbstractQueuedSynchronizer 为实现依赖于先进先出队列的阻塞锁和相关同步器(信号量、事件等等)提供的一个框架,它依靠int值来表示状态
  • Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set (wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用。这个是被绑定在Lock上一起使用的。
  • Lock 实现了比synchronized更多的功能,需要注意的是,为了确保可以释放锁,需要在finally语句块中unlock。
  • LockSupport LockSupport是用来创建锁和其他同步类的基本线程阻塞原语。LockSupport中的park() 和 unpark() 的作用分别是阻塞线程和解除阻塞线程,而且park()和unpark()不会遇到“Thread.suspend 和 Thread.resume所可能引发的死锁”问题。
  • ReadWriteLock 读写锁,读和写是互斥的,多个读锁不互斥,也就是说,在读的时候,不能写,在写的时候,不能读,但是在读的时候可以有多个线程同时读。
  • ReentrantLock 可重入锁
  • ReentrantReadWriteLock 可重入读写锁
  • StampedLock Java 1.8提供了一种读写锁,

2. Condition

Condition是和Lock绑定使用的。Lock#newCondition方法返回一个Condition。
使用方法如下:

  • 创建Lock
  • Lock#newCondition 返回新的Condition (可以多次调用)
  • Condition#await 会导致线程挂起直到signalled,或者中断。
  • Condition#signal 唤醒线程

ArrayBlockingQueue中有大量这样的用法。如图:
这里写图片描述

3. LockSupport

  • park方法能将阻塞线程或者
  • unpark 方法唤醒线程

4. ReentrantReadWriteLock

ReentrantReadWriteLock是locks包中提供的读写锁的一种实现,用法也很简单。一般用jdk提供的ReentrantReadWriteLock。

用法如下

  • 初始化
ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
Lock readLock = readWriteLock.readLock();
Lock writeLock = readWriteLock.writeLock();
  • 在需要读的时候readLock.lock(),用完之后readLock.unlock()
  • 在需要写的时候writeLock.lock(),用完之后writeLock.unlock()

ReentrantReadWriteLock支持锁降级

什么是锁降级呢。从读写角度来看,写的级别是高于读的。咱们看例子

    public static void main(String[] args){
        ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
        final Lock readLock = readWriteLock.readLock();
        final Lock writeLock = readWriteLock.writeLock();
        // 读
        readLock.lock();
        System.err.println("我是读锁");
        // 写
        writeLock.lock();
        System.err.println("我是写锁");

    }

很明显,由于不支持锁升级,因此,会阻塞。输出结果如下
这里写图片描述

我们上面读写翻个顺序。

        // 写
        writeLock.lock();
        System.err.println("我是写锁");
        // 读
        readLock.lock();
        System.err.println("我是读锁");

输出结果如下:
这里写图片描述

锁降级,将写入锁降级为读锁(很好理解,就像写权限要高于读权限一样)

5. ReentrantLock

也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响

这种锁在ArrayBlockingQueue中有用到。
这里写图片描述

关于用法这里就不说了。
ReentrantLock可是实现公平锁

    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

从构造函数中来看,是支持公平锁的。

公平锁,等待时间长的优先获得锁。

6. StampedLock

这里想的半天,还是觉得参考资料里面写的很完美,所以,我就不献丑了。大家去看看吧。


参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值