zoukankan      html  css  js  c++  java
  • 高级同步器:信号量Semaphore

    引自:https://blog.csdn.net/Dason_yu/article/details/79734425

    一、信号量
    一个计数信号量。从概念上讲,信号量维护了一个许可集。Semaphore经常用于限制获取某种资源的线程数量。在java并发中,即Semaphore维护指定数量许可,当Semaphore中有额外(空闲)的许可时,线程获取到许可信号后(调用acquire()),线程才允许被执行,否则将被阻塞。当线程执行完毕,就会将占用的许可释放(调用release())。

    此类的构造方法可选地接受一个公平 参数。当设置为 false 时,此类不对线程获取许可的顺序做任何保证。当公平设置为 true 时,信号量保证对于任何调用获取方法的线程而言,都按照处理它们调用这些方法的顺序(即先进先出;FIFO)来选择线程、获得许可。注意,FIFO 排序必然应用到这些方法内的指定内部执行点。所以,可能某个线程先于另一个线程调用了 acquire,但是却在该线程之后到达排序点,并且从方法返回时也类似。

    二、用法

    package com.thread;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Semaphore;
    
    /**
     * 信号量一般用于用于限制获取某种资源的线程数量
     * 
     * @author Dason
     *
     */
    public class SemaphoreTest {
        
        public static void main(String[] args) {
            ExecutorService service = Executors.newCachedThreadPool();
            // 创建一个管理 3 个许可的信号量
            final Semaphore sp = new Semaphore(3);
            for (int i = 0; i < 10; i++) {
                Runnable runnable = new Runnable() {
                    public void run() {
                        try {
                            // 获取一个许可,若没有则被阻塞
                            sp.acquire();
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                        // availablePermits(): 返回此信号量中当前可用的许可数.
                        System.out.println(
                                "线程" + Thread.currentThread().getName() + "进入,当前已有" + (3 - sp.availablePermits()) + "个并发");
                        try {
                            Thread.sleep((long) (Math.random() * 100));
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("线程" + Thread.currentThread().getName() + "即将离开");
                        // 释放一个许可.
                        sp.release();
                        // 下面代码有时候执行不准确,因为其没有和上面的代码合成原子单元
                        System.out.println(
                                "线程" + Thread.currentThread().getName() + "已离开,当前已有" + (3 - sp.availablePermits()) + "个并发");
                    }
                };
                service.execute(runnable);
            }
        }
    
    }
  • 相关阅读:
    falsk 自定义中间件
    练习题
    4.12 作业题
    测试笔试题2
    测试笔试题
    简答题
    单选题
    普华和诚测试笔试试题
    缺陷报告
    测试用例点
  • 原文地址:https://www.cnblogs.com/x-jingxin/p/10650530.html
Copyright © 2011-2022 走看看