Semaphore(计数信号量)

介绍

         Semaphore(计数信号量)是一个线程工具类,主要用于描述多线程争夺有限资源的场景。在Semaphore初始化时会传入一个最大的信号量数字,其他的线程可以通过同一Semaphore实例的acquire(count)方法来获取信号量,成功获取的可以继续执行,没有获取到的需要在这里等待,以此来控制对有限资源的使用,信号量获取成功的线程在使用完资源后可以使用release(count)方法释放获取到的信号量,供其他线程获取使用。

常用方法列表

//构造函数,以传入数字个信号量作为最大信号量初始化
Semaphore(int permits);
//构造函数,可以额外指定锁的类型,true为公平锁,false为非公平锁
Semaphore(int permits, boolean fair);
//获取一个信号量,否则等待
void acquire();
//获取 permits 个信号量,否则等待
void acquire(int permits);
//获取一个信号量,否则等待且不允许中断
void acquireUninterruptibly();
//获取 permits 个信号量,否则等待且不允许中断
void acquireUninterruptibly(int permits);
//尝试获取一个信号量,获取成功返回true
boolean tryAcquire();
//尝试获取一个信号量,直到出了指定的等待时间,获取成功返回true
boolean tryAcquire(long timeout, TimeUnit unit);
//尝试获取 permits 个信号量,获取成功返回true
boolean tryAcquire(int permits);
//尝试获取 permits 个信号量,直到出了指定的等待时间,获取成功返回true
boolean tryAcquire(int permits, long timeout, TimeUnit unit);
//释放一个获取的信号量
void release();
//释放 permits 个获取的信号量
void release(int permits);
//返回当前可用的信号量数目,此方法通常用于调试
int availablePermits();
//返回立即可用的所有许可个数,并且将可用许可置0
int drainPermits();
//判断是否存在等待获取信号量的线程
boolean hasQueuedThreads();
//获取等待获取信号量的线程数目
int getQueueLength();

应用示例

public class SemaphoreTest {

    private static int SEM_MAX = 10;

    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(SEM_MAX);
        ExecutorService pool = Executors.newFixedThreadPool(3);
        pool.execute(new MyTask(semaphore,4));
        pool.execute(new MyTask(semaphore,5));
        pool.execute(new MyTask(semaphore,7));
        System.out.println("主线程运行到这里");
        pool.shutdown();
        System.out.println("主线程运行结束");
    }


    static class MyTask implements Runnable{

        private Semaphore semaphore;    // 信号量
        private int count;              // 申请信号量的大小

        public MyTask(Semaphore semaphore, int count) {
            this.semaphore = semaphore;
            this.count = count;
        }

        @Override
        public void run() {
            try {
                //获取count个信号量,如果获取不到则等待
                semaphore.acquire(count);
                Thread thread = Thread.currentThread();
                System.out.println(thread.getName()+"获取到信号量:"+count);
                Thread.sleep(3000);
                System.out.println(thread.getName()+"运行结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                //释放count个信号量
                semaphore.release(count);
                System.out.println(Thread.currentThread().getName()+"释放信号量:"+count);
            }
        }
    }
}

运行结果

pool-1-thread-1获取到信号量:4
主线程运行到这里
pool-1-thread-2获取到信号量:5
主线程运行结束
pool-1-thread-1运行结束
pool-1-thread-2运行结束
pool-1-thread-2释放信号量:5
pool-1-thread-1释放信号量:4
pool-1-thread-3获取到信号量:7
pool-1-thread-3运行结束
pool-1-thread-3释放信号量:7
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值