zoukankan      html  css  js  c++  java
  • Java并发编程系列之Semaphore详解

    简单介绍

    我们以饭店为例,假设饭店只有三个座位,一开始三个座位都是空的。这时如果同时来了三个客人,服务员人允许他们进去用餐,然后对外说暂无座位。后来的客人必须在门口等待,直到有客人离开。这时,如果有一个客人离开,服务员告诉客人,可以进来用餐,如果又有客人离开,则又可以进来客人用餐,如此往复。
    在这个饭店中,座位是公共资源,每个人好比一个线程,服务员起的就是信号量的作用。信号量是一个非负整数,表示了当前公共资源的可用数目(在上面的例子中可以用空闲的座位类比信号量),当一个线程要使用公共资源时(在上面的例子中可以用客人比线程),首先要查看信号量,如果信号量的值大于1,则将其减1,然后去占有公共资源。如果信号量的值为0,则线程会将自己阻塞,直到有其它线程释放公共资源。

    1、简单介绍Semaphore

    a、可用来控制同时访问特定资源的线程数量,以此来达到协调线程工作。
    b、维护了一个虚拟的资源池,如果许可为0则线程阻塞等待,直到许可大于0时又可以有机会获取许可了。
    c、 内部也有公平锁、非公平锁来访问资源的静态内部类。

    2、Semaphore方法

    a、public Semaphore(int permits);// 创建一个给定许可数量的信号量对象,且默认以非公平锁方式获取资源
    b、public Semaphore(int permits, boolean fair);//创建一个给定许可数量的信号量对象,且是否公平方式由传入的fair布尔参数值决定
    c、public void acquire() ;//从此信号量获取一个许可,当许可数量小于零时,则阻塞等待
    d、public void acquire(int permits) ;//从此信号量获取permits个许可,当许可数量小于零时,则阻塞等待,但是当阻塞等待的线程被唤醒后发现被中断过的话则会抛InterruptedException异常
    e、public void acquireUninterruptibly(int permits) ;从此信号量获取permits个许可,当许可数量小于零时,则阻塞等待,但是当阻塞等待的线程被唤醒后发现被中断过的话则不会抛InterruptedException异常
    f、public void release();//释放一个许可
    g、public void release(int permits);释放permits个许可
    以上只是列出主要方法名,方法详细解释,Semaphore类上面都有注释。就不一一累出来了。

    举一个简单例子,帮助我们加深印象

    /**
     * @author shuliangzhao
     * @Title: SemaPhoreTest
     * @ProjectName design-parent
     * @Description: TODO
     * @date 2019/6/5 22:50
     */
    public class SemaPhoreTest {
    
        private Semaphore semaphore = new Semaphore(3);
    
        class TaskThread implements Runnable{
    
            private int id;
    
            public TaskThread(int id) {
                this.id = id;
            }
    
            @Override
            public void run() {
                try {
                    semaphore.acquire();
                    System.out.println("Thread " + id + " is working");
                    Thread.sleep(2000);
                    semaphore.release();
                    System.out.println("Thread " + id + " is over");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static void main(String[] args) {
            SemaPhoreTest semaPhoreTest = new SemaPhoreTest();
            /*for (int i = 0;i<6;i++) {
                Thread thread = new Thread(semaPhoreTest.new TaskThread(i));
                thread.start();
            }*/
            ExecutorService executorService = Executors.newCachedThreadPool();//同步队列线程
            executorService.submit(semaPhoreTest.new TaskThread(1));
            executorService.submit(semaPhoreTest.new TaskThread(2));
            executorService.submit(semaPhoreTest.new TaskThread(3));
            executorService.submit(semaPhoreTest.new TaskThread(4));
            executorService.submit(semaPhoreTest.new TaskThread(5));
            executorService.submit(semaPhoreTest.new TaskThread(6));
            executorService.submit(semaPhoreTest.new TaskThread(7));
            executorService.shutdown();
        }
    }
    

    运行结果

     
  • 相关阅读:
    vmware里面的名词 vSphere、vCenter Server、ESXI、vSphere Client
    SQL Server2014 SP2新增的数据库克隆功能
    看完SQL Server 2014 Q/A答疑集锦:想不升级都难!
    Windows Server 2012 NIC Teaming 网卡绑定介绍及注意事项
    最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目
    基于本地存储的kvm虚拟机在线迁移
    SQL Server 数据加密功能解析
    android开发之GestureDetector手势识别(调节音量、亮度、快进和后退)
    Datazen介绍
    jquery智能弹出层,自己主动推断位置
  • 原文地址:https://www.cnblogs.com/treeshu/p/11026065.html
Copyright © 2011-2022 走看看