前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试系列之-信号量Semaphore(JAVA基础)

面试系列之-信号量Semaphore(JAVA基础)

作者头像
用户4283147
发布2023-09-11 15:53:36
2300
发布2023-09-11 15:53:36
举报
文章被收录于专栏:对线JAVA面试

概述

控制同一时间并发线程的数目。能够完成对于信号量的控制,可以控制某个资源可被同时访问的个数。提供了两个核心方法——acquire()方法和release()方法。acquire()方法表示获取一个许可,如果没有则等待,release()方法则是在操作完成后释放对应的许可。Semaphore维护了当前访问的个数,通过提供同步机制来控制同时访问的个数。Semaphore可以实现有限大小的链表。

使用场景

Semaphore常用于仅能提供有限访问的资源,比如:数据库连接数。

代码示例

每次获取并释放一个许可,示例代码如下:

代码语言:javascript
复制
package io.binghe.concurrency.example.aqs;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
@Slf4j
public class SemaphoreExample {
  private static final int threadCount = 200;
    public static void main(String[] args) throws InterruptedException {
    ExecutorService exec = Executors.newCachedThreadPool();
    final Semaphore semaphore  = new Semaphore(3);
    for (int i = 0; i < threadCount; i++){
      final int threadNum = i;
      exec.execute(() -> {
        try {
          semaphore.acquire();  //获取一个许可
          test(threadNum);
          semaphore.release();  //释放一个许可
       } catch (InterruptedException e) {
          e.printStackTrace();
       }
     });
   }
    exec.shutdown();
 }
  private static void test(int threadNum) throws InterruptedException {
    log.info("{}", threadNum);
    Thread.sleep(1000);
 }
}

每次获取并释放多个许可,示例代码如下:

代码语言:javascript
复制
package io.binghe.concurrency.example.aqs;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
@Slf4j
public class SemaphoreExample {
  private static final int threadCount = 200;
  public static void main(String[] args) throws InterruptedException {
    ExecutorService exec = Executors.newCachedThreadPool();
    final Semaphore semaphore  = new Semaphore(3);
    for (int i = 0; i < threadCount; i++){
      final int threadNum = i;
      exec.execute(() -> {
        try {
          semaphore.acquire(3);  //获取多个许可
          test(threadNum);
          semaphore.release(3);  //释放多个许可
       } catch (InterruptedException e) {
          e.printStackTrace();
       }
     });
   }
    log.info("finish");
    exec.shutdown();
 }
  private static void test(int threadNum) throws InterruptedException {
    log.info("{}", threadNum);
    Thread.sleep(1000);
 }
}

假设有这样一个场景,并发太高了,即使使用Semaphore进行控制,处理起来也比较棘手。假设系统当前允许的最高并发数是3,超过3后就需要丢弃,使用Semaphore也能实现这样的场景,示例代码如下:

代码语言:javascript
复制
package io.binghe.concurrency.example.aqs;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
@Slf4j
public class SemaphoreExample {
  private static final int threadCount = 200;
  public static void main(String[] args) throws InterruptedException {
    ExecutorService exec = Executors.newCachedThreadPool();
    final Semaphore semaphore  = new Semaphore(3);
    for (int i = 0; i < threadCount; i++){
      final int threadNum = i;
      exec.execute(() -> {
        try {
          //尝试获取一个许可,也可以尝试获取多个许可,
          //支持尝试获取许可超时设置,超时后不再等待后续线程的执行
          //具体可以参见Semaphore的源码
          if (semaphore.tryAcquire()) {
            test(threadNum);
            semaphore.release();  //释放一个许可
         }
       } catch (InterruptedException e) {
          e.printStackTrace();
       }
     });
   }
    log.info("finish");
    exec.shutdown();
 }
  private static void test(int threadNum) throws InterruptedException {
    log.info("{}", threadNum);
    Thread.sleep(1000);
 }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 对线JAVA面试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 使用场景
  • 代码示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档