美文网首页
并发工具类 Semaphore

并发工具类 Semaphore

作者: 少博先生 | 来源:发表于2017-10-15 19:09 被阅读0次

上篇介绍了内部使用AQS的并发工具类CountDownLatch,接下来我要介绍的并发工具类Semaphore内部同样使用了AQS。

简介

信号量(Semaphore),有时被称为信号灯,一个控制访问多个共享资源的计数器,负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。
从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。拿到信号量的线程可以进入代码,否则就等待。通过acquire()和release()获取和释放访问许可。

继续拿上篇中的吃火锅案例,假设这家小肥羊的洗手间比较高级,洗手间一共有五个坑位,洗手间门有一个信号灯,就跟火车上那个相似,但是火车上的高级,可以显示洗手间当前的可用坑位个数。那么这个五个坑位就是公共资源,信号灯就是Semaphore,要用洗手间的顾客就是线程。

构造方法
构造方法

如果以公平方式执行,则线程将会按到达的顺序(FIFO)执行,如果是非公平,则可以后请求的有可能排在队列的头部。

acquire()获取资源
acquire()

还是老套路,调用AQS的acquireSharedInterruptibly(int arg)

AQS的acquireSharedInterruptibly(int arg)

公平锁和非公平锁的获取资源是不一样,先看公平锁的:

公平锁的tryAcquireShared(int arg)

非公平锁的:

公平锁的nonfairTryAcquireShared(int arg)
release() 释放资源
release() AQS的releaseShared(int arg)

公平锁和非公平锁的获取资源不一样,但释放资源是一样的。

tryReleaseShared(int releases)

案例

public class AA implements Runnable {
    private Semaphore semaphore;
    private int id;
    public AA(Semaphore semaphore, int id) {
        this.semaphore = semaphore;
        this.id = id;
    }

    @Override
    public void run() {
        try {
            //获取坑位
            semaphore.acquire();
            System.out.println("第 " + id  + " 个人正在使用");
            Thread.sleep((long)(Math.random() * 1000));
            //使用完后,出洗手间,释放坑位
            semaphore.release();
            System.out.println("第 " + id + " 个人用完了");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class GoWC {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(5);

        ExecutorService se = Executors.newCachedThreadPool();
        se.submit(new AA(semaphore,1));
        se.submit(new AA(semaphore,2));
        se.submit(new AA(semaphore,3));
        se.submit(new AA(semaphore,4));
        se.submit(new AA(semaphore,5));
        se.submit(new AA(semaphore,6));
        se.submit(new AA(semaphore,7));
        se.submit(new AA(semaphore,8));
        se.submit(new AA(semaphore,9));
        se.submit(new AA(semaphore,10));
        se.shutdown();
    }
}

运行结果:

对于这个结果,感觉有点不太对,比如第5个人释放后,第6个人使用是没问题的,但为什么第7个人也是正在使用???这时同时存在6个线程一块执行,不知道哪写错了。。哪位同学看出问题了,望指出,3Q!

总结

本篇主要介绍了基于AQS的并发工具类Semaphore,起一个信号灯的作用,有公平模式和非公平模式之分,获取公共资源使用acquire,公平模式下的acquire比非公平模式下的acquire多了检查当前线程是否在队列最前端这一步骤,释放资源使用release,公平模式和非公平模式一致。

相关文章

  • Java并发编程之工具类

    一、并发工具类 JDK1.5 引入常用并发工具类:CountDownLatch/Semaphore/CyclicB...

  • 高并发(10)- 线程并发工具类-Semaphore

    @[TOC](高并发(10)- 线程并发工具类-Semaphore) 前言 上篇文章讲解了线程的并发工具类之Cyc...

  • 并发工具类 Semaphore

    上篇介绍了内部使用AQS的并发工具类CountDownLatch,接下来我要介绍的并发工具类Semaphore内部...

  • 并发工具类-Semaphore

    1.使用示例 多个线程从数据库池拿固定数量的连接,用完归还数据库池。用信号量来控制数据库池可用连接的数量,进行流控...

  • Semaphore

    Semaphore Semaphore 是 Java 并发包中提供的一个工具类,翻译过来为“信号量”,作用是控制并...

  • Semaphore源码分析

    1. Semaphore 定义 Semaphore 主要用于限量控制并发执行代码的工具类, 其内部通过 一个 pe...

  • Semaphore 源码分析 (基于Java 8)

    1. Semaphore 定义 Semaphore 主要用于限量控制并发执行代码的工具类, 其内部通过 一个 pe...

  • 并发工具类(3):Semaphore

    简介 Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资...

  • 并发工具类之Semaphore

    Semaphore(信号量) 定义 先看Java API中的定义 A counting semaphore. Co...

  • 理解Semaphore

    Semaphore 是什么 Semaphore 信号量,是JDK的并发包中提供了一个非常有用的工具类。可以控制某个...

网友评论

      本文标题:并发工具类 Semaphore

      本文链接:https://www.haomeiwen.com/subject/gdlcuxtx.html