Java中的Semaphore信号量简析

 更新时间:2023年12月16日 09:07:12   作者:小晨想好好学习  
这篇文章主要介绍了Java中的Semaphore信号量简析,Semaphore:信号量,用来限制能同时访问共享资源的线程上限,使用Semaphore实现简单连接池,对比享元模式下的实现(用wait和notify),性能和可读性要更好,需要的朋友可以参考下

一、是什么?

Semaphore:信号量,用来限制能同时访问共享资源的线程上限

二、简单使用

public class TestSemaphore {
    public static void main(String[] args) {
        // 1. 创建 semaphore 对象
        Semaphore semaphore = new Semaphore(3);
        // 2. 10个线程同时运行
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    log.debug("running...");
                    sleep(1);
                    log.debug("end...");
                } finally {
                    semaphore.release();
                }
            }).start();
        }
    }
}

结果:始终只有三个线程处于正在运行的状态

在这里插入图片描述

三、semaphore应用

  • 使用semaphore限流,在访问高峰期时,让请求线程阻塞。当然它只适合限制单机线程数量,并且是仅限制线程数,而不是限制资源数(例如连接数)
  • 使用Semaphore实现简单连接池,对比享元模式下的实现(用wait和notify),性能和可读性要更好
class Pool {
    // 1. 连接池大小
    private final int poolSize;
    // 2. 连接对象数组
    private Connection[] connections;
    // 3. 连接状态数组 0 表示空闲, 1 表示繁忙
    private AtomicIntegerArray states;
    private Semaphore semaphore;
    // 4. 构造方法初始化
    public Pool(int poolSize) {
        this.poolSize = poolSize;
        // 让许可数与资源数一致
        this.semaphore = new Semaphore(poolSize);
        this.connections = new Connection[poolSize];
        this.states = new AtomicIntegerArray(new int[poolSize]);
        for (int i = 0; i < poolSize; i++) {
            connections[i] = new MockConnection("连接" + (i+1));
        }
    }
    // 5. 借连接
    public Connection borrow() {// t1, t2, t3
        // 获取许可
        try {
            semaphore.acquire(); // 没有许可的线程,在此等待
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < poolSize; i++) {
            // 获取空闲连接
            if(states.get(i) == 0) {
                if (states.compareAndSet(i, 0, 1)) {
                    log.debug("borrow {}", connections[i]);
                    return connections[i];
                }
            }
        }
        // 不会执行到这里
        return null;
    }
    // 6. 归还连接
    public void free(Connection conn) {
        for (int i = 0; i < poolSize; i++) {
            if (connections[i] == conn) {
                states.set(i, 0);
                log.debug("free {}", conn);
                semaphore.release();
                break;
            }
        }
    }
}

四、Semaphore原理

在这里插入图片描述

在这里插入图片描述

到此这篇关于Java中的Semaphore信号量简析的文章就介绍到这了,更多相关Semaphore信号量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于springboot redirect重定向路径问题总结

    基于springboot redirect重定向路径问题总结

    这篇文章主要介绍了springboot redirect重定向路径问题总结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • SpringBoot请求转发的方式小结

    SpringBoot请求转发的方式小结

    本文主要介绍了SpringBoot请求转发的方式,一共有两大类,一种是controller控制器转发一种是使用HttpServletRequest进行转发,本文就详细的介绍一下,感兴趣的可以了解一下
    2023-09-09
  • 基于Java实现模板填充Word

    基于Java实现模板填充Word

    这篇文章主要为大家详细介绍了如何用 Java 实现按产品经理提供的 Word 模板填充数据,并以 word 或 pdf 形式导出,有需要的小伙伴可以参考一下
    2025-01-01
  • 详解Java如何实现加密或者解密PDF文档

    详解Java如何实现加密或者解密PDF文档

    PDF文档加密是一种用于保护文件内容的功能。这篇文章主要介绍了Java实现加密或者解密PDF文档的方法,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-03-03
  • SpringMvc后台接收json数据中文乱码问题详解

    SpringMvc后台接收json数据中文乱码问题详解

    这篇文章主要介绍了SpringMvc后台接收json数据中文乱码问题详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • java利用CompletionService保证任务先完成先获取到执行结果

    java利用CompletionService保证任务先完成先获取到执行结果

    这篇文章主要为大家详细介绍了java如何利用CompletionService来保证任务先完成先获取到执行结果,文中的示例代码讲解详细,需要的可以参考下
    2023-08-08
  • Spring搭配Ehcache实例解析

    Spring搭配Ehcache实例解析

    这篇文章主要为大家详细介绍了Spring搭配Ehcache实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • 利用Maven添加工程版本信息及时间戳

    利用Maven添加工程版本信息及时间戳

    这篇文章主要介绍了利用Maven添加工程版本信息及时间戳方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • SpringMVC集成FastJson使用流程详解

    SpringMVC集成FastJson使用流程详解

    如果你使用 Spring MVC 来构建 Web 应用并对性能有较高的要求的话,可以使用 Fastjson 提供的FastJsonHttpMessageConverter 来替换 Spring MVC 默认的 HttpMessageConverter 以提高 @RestController @ResponseBody @RequestBody 注解的 JSON序列化速度
    2023-02-02
  • Java Map接口及其实现类原理解析

    Java Map接口及其实现类原理解析

    这篇文章主要介绍了Java Map接口及其实现类原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03

最新评论