Semaphore信号量

Semaphore信号量

在这里插入图片描述


- Semaphore 可以用来限制或管理数量有限资源的使用情况 - 信号量的作用是用来维护一个“许可证”,的计数,线程可以获取 许可证,那信号量剩余许可证就减一,线程也可以是否一个许可证,那剩余的许可证就加一,当信号量拥有的许可证为0时,那么下一个线程想获得许可证,就要进行等待,直到另外线程释放许可证
信号量使用流程 : 1.初始化Semaphore 并指定许可证的数量 : 2.在需要被现在的代码前加acquire() 或者 acquireUninterruptibly()方法 : 3.在任务结束后,调用release() 来释放许可证
信号量主要方法使用
1.new Semaphore(int permits,boolean fair): 这里可以设置是否使用公平策略,如果传入true,那么Semaphore 会把之前等待的线程放到FIFO的队列里,以便于当有了新的许可证,可以分发给之前等了最长时间的线程
2.tryAcquire() : 看看现在有没有空闲的许可证,如果有的话就获取,如果没有的话也没关系,我不必陷入阻塞,我可以i去做别的事情,过一会再来查看许可证的空闲情况
3.tryAcquire(timeout) : 和tryAcquire()一样,但是多了超时时间,比如 “在3秒内获取不到许可证,我去做别的事情”
  • 代码演示
package com.yxl.task;


import lombok.SneakyThrows;
import org.omg.PortableInterceptor.INACTIVE;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.*;

/**
 * Semaphore 演示demo
 */
public class SemaphoreDemo {

     static Semaphore semaphore =new Semaphore(3,true);
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(50);
        for (int i = 0; i < 50; i++) {
            executorService.execute(new Task());
        }
        executorService.shutdown();

    }
    static class Task implements Runnable{
        @SneakyThrows
        @Override
        public void run() {
            semaphore.acquire();
            System.out.println(Thread.currentThread().getName()+"拿到来许可证");
            Thread.sleep(200);
            System.out.println(Thread.currentThread().getName()+"释放了许可证");
            semaphore.release();
        }
    }
}

在这里插入图片描述
运行结果,会发现他是3个那到,三个释放 执行线程

我们修改获取信号量到参数

@SneakyThrows
        @Override
        public void run() {
            semaphore.acquire(3);
            System.out.println(Thread.currentThread().getName()+"拿到来许可证");
            Thread.sleep(200);
            System.out.println(Thread.currentThread().getName()+"释放了许可证");
            semaphore.release(3);
        }

每次运行一个线程都会拿到3个许可证

  • 可以根据我们到需求一次获取或者释放多个许可证
  • 比如TaskA会调用很消耗资源到 method1() 而TaskB 调用到是不太消耗资源到 mehod2(), 假设我们一共有5个许可证,那么我们就可以要求TaskA 获取5个许可证才能执行,这样避免了A B 同时运行到情况,我们可以根据直接到需求和里分配资源

注意点

1.获取和释放到许可证数量必须一致,否则比如每次都获取2个但是只释放一个甚至不释放,随着时间到推移,到最后许可证数量不够用,会导致程序卡死。

2.注意在初始化Semaphore的时候设置公平性,一般设置为 true 更合理

3.信号量的作用,除了控制临界区最多同时有N个线程访问外,林一个作用是可以实现“条件等待”,例如 线程1需要在线程2完成准备工作后才能开始工作,那么线程1 acquire() , 而线程2完成任务后release(),这样电话,相当于轻量级的CountDownLatch

个人博客地址:http://blog.yanxiaolong.cn/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值