JAVA同步锁Semaphore

简介: JAVA同步锁Semaphore

Semaphore(/ˈseməfɔːr/)介绍

Semaphore,俗称信号量,它是操作系统中PV操作的原语在java的实现,它也是基于AbstractQueuedSynchronizer实现的。

Semaphore的功能非常强大,大小为1的信号量就类似于互斥锁,通过同时只能有一个线程获取信号量实现。大小为n(n>0)的信号量可以实现限流的功能,它可以实现只能有n个线程同时获取信号量

PV操作

PV操作是操作系统一种实现进程互斥与同步的有效方法。 PV操作与信号量(S)的处理相关,P表示通过的意思,V表示释放的意思。用PV操作来管理共享资源时,首先要确保PV操作自身执行的正确性。

P操作的主要动作是:

①S减1;

②若S减1后仍大于或等于0,则进程继续执行;

③若S减1后小于0,则该进程被阻塞后放入等待该信号量的等待队列中,然后转进程调度。

V操作的主要动作是:

①S加1;

②若相加后结果大于0,则进程继续执行;

③若相加后结果小于或等于0,则从该信号的等待队列中释放一个等待进程,然后再返回原进程继续执行或转进程调度。

Semaphore 常用方法

构造器

  • permits 表示许可证的数量(资源数)
  • fair 表示公平性,如果这个设为 true 的话,下次执行的线程会是等待最久的线程

常用方法

public void acquire() throws InterruptedException 
public boolean tryAcquire() 
public void release() 
public int availablePermits() 
public final int getQueueLength() 
public final boolean hasQueuedThreads() 
protected void reducePermits(int reduction) 
protected Collection<Thread> getQueuedThreads()
  • acquire() 表示阻塞并获取许可
  • tryAcquire() 方法在没有许可的情况下会立即返回 false,要获取许可的线程不会阻塞
  • release() 表示释放许可
  • int availablePermits():返回此信号量中当前可用的许可证数。
  • int getQueueLength():返回正在等待获取许可证的线程数。
  • boolean hasQueuedThreads():是否有线程正在等待获取许可证。
  • void reducePermit(int reduction):减少 reduction 个许可证
  • Collection getQueuedThreads():返回所有等待获取许可证的线程集合

应用场景

可以用于做流量控制,确保同一时间最多只有指定数量的线程在工作,特别是公用资源有限的应用场景

限流

// 声明3个窗口  state:  资源数
Semaphore windows = new Semaphore(3);
for (int i = 0; i < 5; i++) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                // 占用窗口    加锁
                windows.acquire();
                System.out.println(Thread.currentThread().getName() + ": 开始买票");
                //模拟买票流程
                Thread.sleep(5000);
                System.out.println(Thread.currentThread().getName() + ": 购票成功");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // 释放窗口
                windows.release();
            }
        }
    }).start();
}

Semaphore 原理

   创建Semaphore对象将state设置为指定值。调用acquire方法使用CAS将state减掉指定值,同时判断减掉后的值是否大于0,如果小于0,则将当前线程挂起并加入阻塞队列。调用release方法将state加上指定值,未成功前一直死循环,直到成功,然后唤醒等待队列中的线程。

相关文章
JAVA并发编程系列(7)Semaphore信号量剖析
腾讯T2面试,要求在3分钟内用不超过20行代码模拟地铁安检进站过程。题目设定10个安检口,100人排队,每人安检需5秒。实际中,这种题目主要考察并发编程能力,特别是多个线程如何共享有限资源。今天我们使用信号量(Semaphore)实现,限制同时进站的人数,并通过信号量控制排队和进站流程。并详细剖析信号量核心原理和源码。
|
Java
【源码】【Java并发】【AQS】从ReentrantLock、Semaphore、CutDownLunch、CyclicBarrier看AQS源码
前言 主播觉得,AQS的原理,就是通过这2个队列的协助,实现核心功能,同步队列(CLH队列)和条件队列(Condition队列)。 同步队列(CLH队列) 作用:管理需要获...
274 18
【源码】【Java并发】【AQS】从ReentrantLock、Semaphore、CutDownLunch、CyclicBarrier看AQS源码
|
Java 测试技术 开发者
Java面试题:解释CountDownLatch, CyclicBarrier和Semaphore在并发编程中的使用
Java面试题:解释CountDownLatch, CyclicBarrier和Semaphore在并发编程中的使用
278 12
|
API
java-多线程-CountDownLatch(闭锁) CyclicBarrier(栅栏) Semaphore(信号量)-
java-多线程-CountDownLatch(闭锁) CyclicBarrier(栅栏) Semaphore(信号量)-
252 1
|
存储 并行计算 Java
Java8中JUC包同步工具类深度解析(Semaphore,CountDownLatch,CyclicBarrier,Phaser)
Java8中JUC包同步工具类深度解析(Semaphore,CountDownLatch,CyclicBarrier,Phaser)
258 2
|
算法 安全 Java
Java性能优化(五)-多线程调优-Lock同步锁的优化
基本特点Lock锁的基本操作通常基于乐观锁实现,尽管在某些情况下(如阻塞时)它也可能采用悲观锁的策略。通过对比图,我们可以清晰地看到两种同步锁的基本特点。Lock同步锁与Synchronized的比较在Java中,同步锁机制是确保多线程安全访问共享资源的重要手段。与JVM隐式管理锁的Synchronized相比,Lock同步锁(以下简称Lock锁)提供了更细粒度的控制,通过显式地获取和释放锁,为开发者提供了更大的灵活性。一、基本特点。
624 1
|
Java
Java Semaphore 信号量详解
Java Semaphore 信号量详解
326 3
|
Java
Java一分钟之-并发编程:线程间通信(Phaser, CyclicBarrier, Semaphore)
【5月更文挑战第19天】Java并发编程中,Phaser、CyclicBarrier和Semaphore是三种强大的同步工具。Phaser用于阶段性任务协调,支持动态注册;CyclicBarrier允许线程同步执行,适合循环任务;Semaphore控制资源访问线程数,常用于限流和资源池管理。了解其使用场景、常见问题及避免策略,结合代码示例,能有效提升并发程序效率。注意异常处理和资源管理,以防止并发问题。
227 2
|
安全 Java 测试技术
今天我们来聊一聊Java中的Semaphore
【5月更文挑战第3天】今天我们来聊一聊Java中的Semaphore
239 3
|
Java 数据库
深入解析Java并发包(JUC)中的Semaphore
深入解析Java并发包(JUC)中的Semaphore