Semaphore 源码分析

本文深入分析了 Java 中的 Semaphore 源码,包括其基本结构、继承关系、核心字段和方法。Semaphore 作为同步工具,利用 AQS 的 state 属性实现资源的共享。文章介绍了公平锁和非公平锁的 acquire 和 release 方法的工作原理,以及在资源释放时如何唤醒等待线程。通过源码阅读,揭示了 Semaphore 如何从信号量演变为锁的机制。
摘要由CSDN通过智能技术生成

Semaphore 源码分析

1. 在阅读源码时做了大量的注释,并且做了一些测试分析源码内的执行流程,由于博客篇幅有限,并且代码阅读起来没有 IDE 方便,所以在 github 上提供JDK1.8 的源码、详细的注释及测试用例。欢迎大家 star、fork !

2. 由于个人水平有限,对源码的分析理解可能存在偏差或不透彻的地方还请大家在评论区指出,谢谢!

1. Semephore 简单介绍

   一般来说,在 Java 中比较常用的同步工具就是 Lock 和 Synchronized 但是 Java 也加入了很多新的机制比如这里提到的信号量。他其实给人的感觉就是操作系统中的信号量,如果一个线程要运行需要获取一个资源进行一次 P 操作,在这里就是调用 acquire 方法,然后运行结束后调用 V 操作,释放这个资源以供其他线程使用,这里的 release 方法。那么如果资源都被其他线程抢光了,那么这个线程只能处于等待状态。也就是 P 操作返回的 -1 。

   上面我们所说的信号量是多值信号量,主要用于进程之间的同步。还有一种称之为二值信号量,也就是操作系统中常提到的 mutex 。对,此时他就是锁!因为做了一个 P 操作后,只有进行 V 操作其他线程才能进入临界区。此时和 Lock 作用一样了。

   下面写个简单的程序来感受一下这个同步工具。

public class SemaphoreTest {
   
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(2);
        for (int i = 0; i < 4; i++) {
            new Thread(()->{
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                }
            }).start();
        }
    }
}

最后输出的如下:
先打印了

Thread-0
Thread-1

隔了一秒打印了

Thread-2
Thread-3

   可以看到临界区内只有两个线程同时执行。其实当我们理解了上一篇文章中的 AQS 我们大概也能猜到 Semaphore 的实现原理,也是借助于 AQS 中的 state 属性,下面具体分析一下 Semaphore 的结构及原理。

2. 基本结构

1. 继承

null

2. 实现

Serializable  感觉好多类都能序列化啊!!有没有觉得。

3. 主要字段

    private final Sync sync;

   好的,就一个锁字段,真干脆,那么证明前面的猜测也是对的,这个 Sync 肯定是一个内部类,继承了 AQS。在上面一篇文章中我们看到了一些 AQS 中的共享锁我没有分析,其实共享锁就是放在这使用的,所以在这篇文章中主要就是介绍 AQS 中剩下的共享锁部分。看一下整体结构。

   有没有觉得很熟悉,简直和 ReentrantLock 结构极其相似。Semaphore的内部类公平锁(FairSync)和非公平锁(NoFairSync)各自实现不同的获取锁方法即tryAcquireShared(int arg),毕竟公平锁和非公平锁的获取稍后不同,而释放锁tryReleaseShared(int arg)的操作交由Sync实现,因为释放操作都是

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值