首页 > 其他分享 >信号量

信号量

时间:2023-12-17 14:33:10浏览次数:30  
标签:AQS lock 信号量 计数器 线程 Semaphore

信号量

信号量是什么

信号量是一种用于控制对共享资源的访问的同步机制,他可以限制同时访问共享资源的线程数量,从而避免资源的竞争和冲突。
使用场景:用于多线程的并发控制,类似于限流。

信号量和限流的异同

信号量和限流的使用场景侧重点不同:

  1. 信号量通常用于控制对共享资源的访问;
  2. 限流用于控制系统的输入和输出流量,防止系统过载;

关注的维度不同

  1. 限流通常是接口维度或系统维度的,一般是分布式下控制的;
  2. 信号量是单机节点下控制的线程并发。

相似之处,都涉及对资源或流量的控制,以保证系统的稳定性;

信号量怎么用

信号量可以使用 java.util.concurrent.Semaphore 类来实现。
你可以通过创建一个信号量对象,然后使用 acquire() 方法来获取信号量,使用 release() 方法来释放信号量。

import java.util.concurrent.Semaphore;

public class SemaphoreExample {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(1); // 创建一个初始值为1的信号量

        try {
            semaphore.acquire(); // 获取信号量
            // 在这里执行需要控制访问的代码
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release(); // 释放信号量
        }
    }
}

用锁模拟信号量

自己实现模拟实现一个信号量,便于理解内部原理

import java.util.concurrent.locks.ReentrantLock;

public class CustomSemaphore {
    private final ReentrantLock lock = new ReentrantLock();
    private volatile int permits;

    public CustomSemaphore(int initialPermits) {
        this.permits = initialPermits;
    }

    public void acquire() throws InterruptedException {
        lock.lock();
        while (permits == 0) {
            lock.unlock();
            Thread.sleep(100); // 休眠一段时间后再尝试获取锁
            lock.lock();
        }
        permits--;
        lock.unlock();
    }

    public void release() {
        lock.lock();
        permits++;
        lock.unlock();
    }
}

信号量满的情况下,是线程等待吗?

是的,当信号量满的情况下,线程会进入等待状态,直到有其他线程释放许可为止。

信号量实现的原理是什么?

信号量的原理是使用一个计数器来控制对共享资源的访问,
当线程希望访问共享资源时,需要先获取信号量。
如果信号量的计数器大于0,则线程可以获取该信号量并将计数器减一,表示占用了一个资源;
如果计数器为0,则线程需要等待,直到有其他线程释放资源,使得计数器增加。
当线程访问完共享资源后,需要释放信号量,将计数器加一,表示释放了一个资源,其他等待的线程可以获取信号量继续访问共享资源。

Semaphore 的内部实现

Semaphore 的内部实现基于同步器 AbstractQueuedSynchronizer (AQS)。
AQS 提供了一个框架,可以用来构建不同类型的同步器,Semaphore 就是其中一种。
Semaphore 内部通过 AQS 的 acquire 和 release 方法来实现许可的获取和释放,以及等待队列的管理。
Semaphore 在内部维护一个计数器,用来表示可用的许可数量,通过 AQS 的状态来实现对计数器的操作和线程的阻塞唤醒。

Semaphore是怎么实现队列等待的

Semaphore 内部通过使用 AQS(AbstractQueuedSynchronizer)来实现队列等待。
当线程尝试获取许可时,如果许可数量不足,线程会被加入到 AQS 的等待队列中,然后被阻塞挂起。
当其他线程释放许可时,AQS 会按照特定的策略唤醒等待队列中的线程,使其有机会再次尝试获取许可。
这样就实现了基于队列的等待机制。

AQS(AbstractQueuedSynchronizer)是 Java 中用于构建同步器的框架,
它提供了一种基于 FIFO 等待队列的同步器实现方式,可以用来构建各种类型的同步器,如 ReentrantLock、Semaphore 等。
AQS 的核心思想是通过内置的队列和状态来实现线程的阻塞和唤醒,从而实现对共享资源的访问控制。

标签:AQS,lock,信号量,计数器,线程,Semaphore
From: https://www.cnblogs.com/chenglc/p/17909048.html

相关文章

  • 信号量、事件组、任务通知:异同及替代应用分析(超细)
    在实时嵌入式系统中,信号量、事件组和任务通知是常用的同步与通信机制,它们在不同场景下有着各自的优势与适用性。本文将深入探讨这三种机制的异同,分析它们的特点及何时可以相互替代,并通过详细的代码演示展示它们的具体应用。1.信号量(Semaphore)1.1特点计数型:信号量是一种计数型的......
  • 信号量
    队列二值信号量(通常用于互斥访问和任务同步互斥,与互斥信号量类似但二值信号量有可能会导致任务优先级翻转的问题所以二值信号量更适合与任务同步)。例1:信号量互斥操作若用于互斥,几个进程(或线程)往往只设置一个信号量sem,它们的操作流程如下图2-1:例2:信号量同步操作当信号量......
  • percpu 读写信号量 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/locking/percpu-rw-semaphore.html"Percpurwsemaphores"是一种新的读写信号量设计,针对读取操作进行了优化。传统的读写信号量存在一个问题,即当多个核心获取读取锁时,包含信号量的缓存行在各个核心的L1缓存之间反复传输,导致性能下降......
  • FreeRTOS--信号量
    示例源码基于FreeRTOSV9.0.0信号量1.概述消息队列用于传输多个数据,但是有时候只需要传递状态,这个状态值需要用一个数值表示,在这种情况下我们只需要维护一个数值,使用信号量效率更高、更节省内存。信号量用来表示资源的个数,它是特殊的队列实现,队列数据项为空。对于二值信号量......
  • C++20(信号量)
    #include<iostream>#include<semaphore>#include<thread>usingnamespacestd;std::counting_semaphore<3>csem(0);//semaphorerelease=condition_variablenotify//semaphoreacquire=condition_variablewaitvoidtask(){......
  • 锁—信号量与管程
    1.基本概念互斥只有一个线程能访问临界区。临界资源多个线程可以共享系统中的资源,但是临界资源只允许一个线程在某一时刻访问。如某些变量、硬件资源。临界区访问临界资源的代码即临界区。2.信号量与管程管程(Monitors)和信号量(Semaphores)是操作系统中用于实现并发......
  • C++11 多线程并发 互斥量、条件变量和信号量
    互斥量Classesmutex(C++11)providesbasicmutualexclusionfacility(class)timed_mutex(C++11)providesmutualexclusionfacilitywhichimplementslockingwithatimeout(class)recursive_mutex(C++11)providesmutualexclusionfacili......
  • FreeRTOS深入教程(信号量源码分析)
    (文章目录)前言本篇文章将为大家讲解信号量,源码分析。在FreeRTOS中,信号量的实现基于队列。这种设计的思想是利用队列的特性来实现信号量,因为信号量可以被视为只能存储0或1个元素的特殊队列。在FreeRTOS中,二进制信号量(BinarySemaphore)通常由一个队列和一个计数器组成......
  • iOS信号量造成线程优先级反转
    在并发队列使用信号量会可能会造成线程优先级反转一、在iOS16&XCode14上遇到-使用信号量造成线程优先级反转问题提醒经过查询资料,发现是在XCode14上增加了工具,比如:ThreadPerformanceChecker(XCode14上默认开启的),这个工具会让APP在运行的时候,发现有例如线程优先级反转......
  • FreeRTOS(2):队列、信号量、互斥量
    1、队列 1.1数据传输方法任务之间如何传输数据 数据个数互斥措施阻塞-唤醒全局变量1无无环形缓冲区多个无无队列多个有有队列又称消息队列,是一种常用于任务间通信的数据结构,队列可以在任务与任务间、中断和任务间传递信息。为什么不使用全局变......