zoukankan      html  css  js  c++  java
  • 并发控制-信号量(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.信号量在获取和释放时,对是否是同一个线程没有限制。

  • 相关阅读:
    关于模式窗体的缓存问题的解决方案
    C# 读取网页
    C# 压缩文件
    C#实现反射调用动态加载的DLL文件中的方法
    在线程中修改窗体控件内容
    C# 启用双缓存,避免ListView控件加载数据时闪烁
    JBuilder2005破解方法
    C# combbox datatable 赋值
    今天感觉到秋凉了~
    烦人的流程图~~~
  • 原文地址:https://www.cnblogs.com/cnxieyang/p/12774532.html
Copyright © 2011-2022 走看看