zoukankan      html  css  js  c++  java
  • 并发编程【Semaphore】

    一、使用场景

    Semaphore 翻译成字面意思为 信号量Semaphore 可以控制同时访问的线程个数

    通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

    信号量主要用于两个目的:

    1. 用于多个共享资源的互斥使用;
    2. 用于并发线程数的控制。

    二、代码实现

    public class SemaphoreDemo {
        public static void main(String[] args) {
            Semaphore semaphore = new Semaphore(3);
    
            for(int i=1; i<=6; i++){
                new Thread(()->{
                    try {
                        // 获取资源
                        semaphore.acquire();
                        System.out.println(Thread.currentThread().getName() + "抢占到了车位");
                        TimeUnit.SECONDS.sleep(3);
                        System.out.println(Thread.currentThread().getName() + "离开了车位");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        // 释放资源
                        semaphore.release();
                    }
                }, String.valueOf(i)).start();
            }
        }
    }
    

    运行结果:

    1抢占到了车位
    3抢占到了车位
    2抢占到了车位
    2离开了车位
    3离开了车位
    1离开了车位
    4抢占到了车位
    6抢占到了车位
    5抢占到了车位
    6离开了车位
    4离开了车位
    5离开了车位
    

    三、大致原理分析

    acquire() :当一个线程调用acquire操作时,它要么成功获取信号量(同时信号量减1),要么一直等下去,直到有线程释放信号量,或超时。

    release():实际上会将信号量的值加1,然后唤醒等待的线程。

    四、特殊使用

    当使用Semaphore semaphore = new Semaphore(1);代码创建建信号量时,实际上就相当于使用 synchronized 进行加锁。

    五、其它 API 方法

    // 用来获取一个许可,若无许可能够获得,则会一直等待,直到获得许可
    public void acquire()
        
    // 获取 permits 个许可    
    public void acquire(int permits)
    
    // 释放许可。注意,在释放许可之前,必须先获获得许可
    public void release() 
        
    // 释放 permits 个许可    
    public void release(int permits)
    

    上面 4 个方法都会被阻塞,如果想立即得到执行结果,可以使用下面几个方法:

    // 尝试获取一个许可,若获取成功,则立即返回 true,若获取失败,则立即返回 false
    public boolean tryAcquire():
    
    // 尝试获取一个许可,若在指定的时间内获取成功,则立即返回 true,否则则立即返回 false
    public boolean tryAcquire(long timeout, TimeUnit unit)
        
    // 尝试获取 permits 个许可,若获取成功,则立即返回 true,若获取失败,则立即返回 false
    public boolean tryAcquire(int permits):
        
    // 尝试获取 permits个许可,若在指定的时间内获取成功,则立即返回 true,否则则立即返回 false
    public boolean tryAcquire(int permits, long timeout, TimeUnit unit): 
        
    // 得到可用的许可数目
    public int availablePermits()
    

    Java新手,若有错误,欢迎指正!

  • 相关阅读:
    ADF_ADF基本概要(汇总)
    DBA_实践指南系列11_Oracle Erp R12性能调优基础(案例)
    DBA_实践指南系列10_Oracle Erp R12诊断功能Diagnostic(案例)
    DBA_实践指南系列9_Oracle Erp R12应用补丁AutoPatch/AutoControl/AutoConfig(案例)
    DBA_实践指南系列8_Oracle Erp R12数据维护模式Adadmin(案例)
    DBA_实践指南系列7_Oracle Erp R12监控OAM(案例)
    DBA_实践指南系列6_Oracle Erp R12工作流通知邮件配置Email(案例)
    DBA_实践指南系列5_Oracle Erp R12日常运维和管理(案例)
    DBA_实践指南系列4_Oracle Erp R12系统备份和恢复Backup(案例)
    DBA_实践指南系列3_Oracle Erp R12系统克隆Clone(案例)
  • 原文地址:https://www.cnblogs.com/Java-biao/p/14497133.html
Copyright © 2011-2022 走看看