控制并发线程数 - Semaphore

什么是Semaphore?

计数信号灯, Semaphore是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。
信号量维护一组许可证,使用acquire()去获取许可证,在未获取到许可证之前会一直阻塞,直到获取到许可证,最后使用release() 释放许可证供其它线程获取。

理解

相信大家都有排队就餐的经验,商场里一家非常火爆的餐厅,两百人来就餐,但是餐厅只有100个位子,前面一百人先进去就餐,后边100人就在外面取号排队,餐厅里面一桌客人走后,后面排队的100人才能进去一人,以此类推,出来一人进去一人,许可证可以理解为就是手中的号,号还没到你你就一直等待,当餐厅走了一个人,空出来一个空位置后,刚好号到你了,你就可以进去了(例子不严谨,只作为理解使用)。

Semaphore构造方法

1、Semaphore(int permits)使用给定的许可数量和非公平性设置创建信号量。
2、Semaphore(int permits, boolean fair)使用给定的许可数量和给定的公平性设置创建一个信号量。
permits : 许可证-可用许可证的初始数量
fair : 设置是公平竞争还是非公平竞争,默认是使用非公平竞争,非公平竞争效率会比公平竞争效率高,因为非公平竞争会减少线程上下文切换,通过减少线程的切换来提高效率,设置为true为公平竞争。

Semaphore方法

类型 方法 描述
void acquire() 从这个信号量获取许可证,阻塞直到有一个可用,或者线程被中断
void acquire(int permits) 从这个信号量获取给定数量的许可证,阻塞直到所有许可证都可用,或者线程被中断
void acquireUninterruptibly() 从这个信号量获取许可证,阻塞直到有一个可用为止。
void acquireUninterruptibly(int permits) 从这个信号量获取给定数量的许可证,阻塞直到所有许可证都可用为止。
int availablePermits() 返回此信号量中当前可用的许可证数
int drainPermits() 获取并返回所有立即可用的许可证
protected Collection<Thread> getQueuedThreads() 返回包含可能正在等待获取的线程的集合
int getQueueLength() 返回等待获取的线程数的估计值
boolean hasQueuedThreads() 查询是否有线程正在等待获取
boolean isFair() 如果此信号量的公平性设置为true,则返回true
protected void reducePermits(int reduction) 减少可用许可证的数量
void release() 释放一个许可证,将其返回给信号量
void release(int permits) 释放给定数量的许可证,将它们返回给信号量
String toString() 返回标识此信号量及其状态的字符串
boolean tryAcquire() 从这个信号量获取许可证,只有在调用时有一个许可证可用时
boolean tryAcquire(int permits) 仅当调用时所有许可证都可用时,才从该信号量获取给定数量的许可证
boolean tryAcquire(int permits, long timeout, TimeUnit unit) 如果在给定的等待时间内所有许可证都可用,并且当前线程没有中断,则从该信号量获取给定数量的许可证
boolean tryAcquire(long timeout, TimeUnit unit) 如果在给定的等待时间内有一个可用,并且当前线程没有中断,则从该信号量获取许可

例子

package com.sy.thread.example;

import java.util.concurrent.Semaphore;

/**
 * Description: thread
 *
 * @author songyu
 */
public class SemaphoreTest1 {

    public static void main(String[] args) {
        //定义一个有2个许可证的信号量
        Semaphore semaphore = new Semaphore(2);
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //获取信号量,获取不到将阻塞,直到获取到许可证
                        semaphore.acquire();
                        System.out.println("线程"+Thread.currentThread().getName() + "获取到许可证,开始执行。。。。。。");
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        //归还许可证
                        semaphore.release();
                        System.out.println("线程"+Thread.currentThread().getName() + "执行完毕,归还许可证");
                    }

                }
            }, String.valueOf(i)).start();
        }
    }

}

输出结果

线程0获取到许可证,开始执行。。。。。。
线程1获取到许可证,开始执行。。。。。。
线程0执行完毕,归还许可证
线程1执行完毕,归还许可证
线程3获取到许可证,开始执行。。。。。。
线程2获取到许可证,开始执行。。。。。。
线程2执行完毕,归还许可证
线程3执行完毕,归还许可证
线程4获取到许可证,开始执行。。。。。。
线程4执行完毕,归还许可证

通过执行结果可以看出,当2个许可证都被拿走后,其它来拿许可证的线程拿不到就一直被阻塞这,直到有的线程归还了许可证,阻塞中的线程抢到了许可证后才可以继续执行。

使用场景

限流

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355