美文网首页
「Java 路线」| Java 中的锁

「Java 路线」| Java 中的锁

作者: 彭旭锐 | 来源:发表于2021-01-03 19:27 被阅读0次

点赞关注,不再迷路,你的支持对我意义重大!

🔥 Hi,我是丑丑。本文 「Java 路线」| 导读 —— 他山之石,可以攻玉 已收录,这里有 Android 进阶成长路线笔记 & 博客,欢迎跟着彭丑丑一起成长。(联系方式在 GitHub)


前言

  • 锁是控制线程访问共享资源的方式

目录


1. 前置知识

这篇文章的内容会涉及以下前置 / 相关知识,贴心的我都帮你准备好了,请享用~


2. 锁的分类

2.1 隐式锁 & 显式锁

  • 隐式锁:使用 synchronized 可以隐式地获取 / 释放锁,虽然具备便捷性,但是加锁 / 释放锁不具备可操作性;
  • 显式锁:从 JDK 1.5 后,新增了 Lock 接口,赋予了加锁 / 释放锁更多可操作性与 synchronized 不具备的同步特性(见 第 3 节)。

2.2 悲观锁 & 乐观锁

区别在于线程是否需要锁住同步资源:

  • 悲观锁:锁住;
  • 乐观锁:不锁住。

2.3 公平锁 & 非公平锁

区别在于是否需要排队竞争锁:

  • 公平锁:排队;
  • 非公平锁:先尝试插队,插队失败再排队。

2.4 可重入锁 & 不可重入锁

区别在于线程获得锁之后是否可以再次获取锁:

  • 可重入锁:可以,线程不阻塞;
  • 非可重入锁:不可以,线程阻塞。

2.5 共享锁 & 排它锁

区别在于多个线程是否能共享同一个锁:

  • 共享锁:能;
  • 排他锁:不能。

3. Lock 接口

Lock 是 JDK 1.5 新增的锁接口,赋予了获得锁 / 释放锁更多可操作性与 synchronized 不具备的同步特性。

3.1 Lock 的使用范式

Lock 的使用范式要点如下:

Lock lock = new ReentrantLock();
lock.lock();
try{
    do something ...
} finally {
    lock.unlock();
} 
  • 1、在 finally{} 块中释放锁,以确保获得锁之后能够释放锁;
  • 2、不要在 try{} 块中获得锁,避免在获取锁时发生异常,最后会无故调用释放锁。

3.2 Lock 和 synchronized 的区别

  • 1、非阻塞地获取锁: 尝试获取锁,如果成功获取则返回 true,否则返回 false,而不是阻塞等待;

  • 2、可中断地获取锁: 获取锁的线程能够响应中断;

  • 3、超时获取锁: 可以指定获取锁的超时时间。

3.3 Lock 的 API

Lock 定义了获取锁 / 释放锁的基本操作,主要 API 如下:

public interface Lock {
    void lock();

    void lockInterruptibly() throws InterruptedException;

    boolean tryLock();

    boolean tryLock(long var1, TimeUnit var3) throws InterruptedException;

    void unlock();

    Condition newCondition();
}
方法 描述
lock() 获得锁
unlock() 释放锁
tryLock() 非阻塞地获取锁
lockInterruptibly() 可中断地获取锁
tryLock(long,TimeUnit) 超时获得锁,只有 3 种情况下会返回:
1、超时
2、获得锁
3、中断

4. AQS 队列同步器

锁是控制线程访问共享资源的方式,但是 Lock 只是一个接口,它是如何实现线程访问控制的呢?事实上,Lock 的实现基本都是通过聚合一个 AQS 队列同步器来实现线程访问控制的。关于 AQS 的内容,请看前置知识:


5. ReentrantLock 可重入锁


6. ReentrantReadWriteLock 读写锁


7. 并发工具类

7.1 CountDownLatch 等待多线程完成

7.2 CyclicBarrier 同步屏障

7.3 Symaphore 信号量

7.4 Exchanger 交换者


8. 总结

  • 锁是控制线程访问同步资源的方式,在 JDK 1.5 之前,锁是通过 synchronized 关键字实现的;

  • Lock 是 JDK 1.5 新增的锁接口,赋予了加锁 / 释放锁更多可操作性与 synchronized 不具备的同步特性:非阻塞地获取锁、可中断地获取锁和超时获取锁。Lock 的实现基本是通过聚合一个 AQS 同步器来进行线程访问控制的;


创作不易,你的「三连」是丑丑最大的动力,我们下次见!

相关文章

  • 「Java 路线」| Java 中的锁

    点赞关注,不再迷路,你的支持对我意义重大!? Hi,我是丑丑。本文 「Java 路线」| 导读 —— 他山之石,可...

  • Java中的锁

    Java中的锁 参考了这篇:Java中的锁分类 公平锁/非公平锁(ReentrantLock/Synchroniz...

  • Java中各种锁的介绍

    ​ Java中各种锁的介绍 前言 Java提供了各种各样的锁,每种锁...

  • Java中的锁

    参考: java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁 Java中的锁--朱小厮 乐观锁和悲观锁 宏观...

  • 同步器AbstractQueuedSynchronizer浅析

    Java中的锁主要有:synchronized锁和JUC(java.util.concurrent)locks包中...

  • Java - 可重入锁ReentrantLock简单用法

    Java - 可重入锁ReentrantLock简单用法 Java 中显示锁的借口和类主要位于java.util....

  • java 锁升级

    java锁升级路线 偏向锁->轻量级锁->重量级锁(互斥量) 1: 正常无锁状态 轻量级锁未锁定状态 偏向锁未锁...

  • synchronized 以及java内置锁

    Java中锁大致上分为两类:一类是显示锁,一类是隐式锁;今天我们重点来分析一下java中隐式锁的实现: java中...

  • J.U.C之Lock ReentrantLock & 锁

    Java中的锁 Java中的锁大体分2类; synchronized修饰的锁; J.U.C中提供的锁,其中核心的就...

  • java中各种锁结合源码深度解析

    java中各种锁介绍 1.公平锁 / 非公平锁 公平锁 在java代码中类名是FairSync。 公平锁是指多个线...

网友评论

      本文标题:「Java 路线」| Java 中的锁

      本文链接:https://www.haomeiwen.com/subject/dxhpoktx.html