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

 

posted @ 2020-04-25 19:03  cnxieyang  阅读(970)  评论(0编辑  收藏  举报
联系邮箱:cnxieyang@163.com