• 并发控制-信号量(Semaphore)


    信号量用来控制有限资源的方法,举例:假如信号量为3,则同时只有3个线程共享。

    概述

      信号量用来控制系统耗时资源的访问,一般我们初始设置了一个公平的信号量,线程在使用时需要申请,用完之后需要释放。

    使用流程

      信号量Semaphore的使用流程如下:

      一般设置公平的信号量-->线程在使用时需要进行require申请-->若可以申请到,则执行自己的逻辑-->执行完成后,需要释放信号量

      -->若未申请到,则可以阻塞,直到申请到。

    主要方法

      信号量的部分常用方法如下:

      1.信号量构造:public Semaphore(int permits, boolean fair) 

      2.获取信号量:public void acquire();acquireUninterruptibly();tryAcquire() ;tryAcquire(long timeout, TimeUnit unit)

      3.释放信号量:release();release(int permits)

    实例代码

      下面我们通过初始化一个3容量的信号量,我们用100个线程去获取这个信号量,每次申请一个信号量,当用完之后,我们释放这一个,如以下实例代码所示:

      

    package com.yang.concurrent;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Semaphore;
    import java.util.stream.IntStream;
    
    public class SemaphoreDemp {
        static Semaphore   semaphore  =new Semaphore(3,true);
    
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            for (int i = 0; i < 100; i++) {
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        try {
                            System.out.println(Thread.currentThread().getName()+"等待获取信号量");
                            semaphore.acquire();
                            System.out.println(Thread.currentThread().getName()+"取到了信号量");
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }finally {
                            System.out.println(Thread.currentThread().getName()+"释放信号量");
                            semaphore.release();
                        }
                    }
                };
                executorService.submit(runnable);
            }
            executorService.shutdown();
        }
    }
    

      运行结果如下图所示:

      

    特殊用法及注意点

      1.申请和释放的信号量必须保持一致,在信号量申请时,比如我们可以申请2个,释放的时候也可以释放2个,这个场景是指程序在运行时,可能需要多个资源

      2.信号量在初始化的时候,可以设置为公平或者非公平,我们一般设置为公平,对耗时长的资源访问时,一般不允许争夺

      3.信号量在获取和释放时,对是否是同一个线程没有限制。

  • 相关阅读:
    (30)导入时如何定制spring-boot依赖项的版本【转载】【从零开始学Spring Boot】
    (29)Spring boot 文件上传(多文件上传)【从零开始学Spring Boot】
    (28)SpringBoot启动时的Banner设置【从零开始学Spring Boot】
    POSIX 消息队列相关问题
    linux系统的7种运行级别
    如何判断是否开启超线程
    (26)改变自动扫描的包【从零开始学Spring Boot】
    (24)Spring Boot环境变量读取和属性对象的绑定【从零开始学Spring Boot】
    (25)Spring Boot使用自定义的properties【从零开始学Spring Boot】
    《将博客搬至CSDN》
  • 原文地址:https://www.cnblogs.com/cnxieyang/p/12774532.html
Copyright © 2020-2023  润新知