Java Lock 接口

2021-03-30  本文已影响0人  向梦而来

Lock

Java AQS

java.util.concurrent.locks.AbstractQueuedSynchronizer 抽象类,简称 AQS ,是一个用于构建锁和同步容器的同步器。事实上concurrent 包内许多类都是基于 AQS 构建。例如 ReentrantLock,Semaphore,CountDownLatch,ReentrantReadWriteLock,等。AQS 解决了在实现同步容器时设计的大量细节问题。

AQS 使用一个 FIFO 的队列表示排队等待锁的线程,队列头节点称作“哨兵节点”或者“哑节点”,它不与任何线程关联。其他的节点与等待线程关联,每个节点维护一个等待状态 waitStatus

什么是 Java Lock 接口?

java.util.concurrent.locks.Lock 接口,比 synchronized 提供更具拓展行的锁操作。它允许更灵活的结构,可以具有完全不同的性质,并且可以支持多个相关类的条件对象。它的优势有:

什么是可重入锁(ReentrantLock)?

synchronized、ReentrantLock 都是可重入的锁,可重入锁相对来说简化了并发编程的开发。

关于 ReentrantLock 类,详细的源码解析,可以看看 《【死磕 Java 并发】—– J.U.C 之重入锁:ReentrantLock》

简单来说,ReenTrantLock 的实现是一种自旋锁,通过循环调用 CAS 操作来实现加锁。它的性能比较好也是因为避免了使线程进入内核态的阻塞状态。想尽办法避免线程进入内核的阻塞状态是我们去分析和理解锁设计的关键钥匙。

🦅 synchronized 和 ReentrantLock 异同?

synchronized 优化以前,它的性能是比 ReenTrantLock 差很多的,但是自从 synchronized 引入了偏向锁,轻量级锁(自旋锁)后,两者的性能就差不多了,在两种方法都可用的情况下,官方甚至建议使用 synchronized

并且,实际代码实战中,可能的优化场景是,通过读写分离,进一步性能的提升,所以使用 ReentrantReadWriteLock 。😝

ReadWriteLock 是什么?

ReadWriteLock ,读写锁是,用来提升并发程序性能的锁分离技术的 Lock 实现类。可以用于 “多读少写” 的场景,读写锁支持多个读操作并发执行,写操作只能由一个线程来操作。

ReadWriteLock 对向数据结构相对不频繁地写入,但是有多个任务要经常读取这个数据结构的这类情况进行了优化。ReadWriteLock 使得你可以同时有多个读取者,只要它们都不试图写入即可。如果写锁已经被其他任务持有,那么任何读取者都不能访问,直至这个写锁被释放为止。

ReadWriteLock 对程序性能的提高主要受制于如下几个因素:

  1. 数据被读取的频率与被修改的频率相比较的结果。
  2. 读取和写入的时间
  3. 有多少线程竞争
  4. 是否在多处理机器上运行

ReadWriteLock 的源码解析,可以看看 《【死磕 Java 并发】—– J.U.C 之读写锁:ReentrantReadWriteLock》

Condition 是什么?

在没有 Lock 之前,我们使用 synchronized 来控制同步,配合 Object 的 #wait()#notify() 等一系列方法可以实现等待 / 通知模式。在 Java SE 5 后,Java 提供了 Lock 接口,相对于 synchronized 而言,Lock 提供了条件 Condition ,对线程的等待、唤醒操作更加详细和灵活。下图是 Condition 与 Object 的监视器方法的对比(摘自《Java并发编程的艺术》):

Condition 与 Object 的监视器方法的对比 Condition 与 Object 的监视器方法的对比

🦅 用三个线程按顺序循环打印 abc 三个字母,比如 abcabcabc ?

LockSupport 是什么?

LockSupport 是 JDK 中比较底层的类,用来创建锁和其他同步工具类的基本线程阻塞。

上一篇 下一篇

猜你喜欢

热点阅读