java semaphore 等待_Java并发编程系列之Semaphore详解

本文详细介绍了Java并发编程中的Semaphore信号量,用于控制对公共资源的访问。Semaphore维护了一个许可池,线程需要获取许可才能访问资源。文章通过饭店座位的例子解释了其工作原理,并列举了Semaphore的主要方法,如acquire()和release()。还提供了一个示例代码,展示了Semaphore如何限制线程同时访问资源的数量,确保线程安全。
摘要由CSDN通过智能技术生成

简单介绍

我们以饭店为例,假设饭店只有三个座位,一开始三个座位都是空的。这时如果同时来了三个客人,服务员人允许他们进去用餐,然后对外说暂无座位。后来的客人必须在门口等待,直到有客人离开。这时,如果有一个客人离开,服务员告诉客人,可以进来用餐,如果又有客人离开,则又可以进来客人用餐,如此往复。

在这个饭店中,座位是公共资源,每个人好比一个线程,服务员起的就是信号量的作用。信号量是一个非负整数,表示了当前公共资源的可用数目(在上面的例子中可以用空闲的座位类比信号量),当一个线程要使用公共资源时(在上面的例子中可以用客人比线程),首先要查看信号量,如果信号量的值大于1,则将其减1,然后去占有公共资源。如果信号量的值为0,则线程会将自己阻塞,直到有其它线程释放公共资源。

1、简单介绍Semaphore

a、可用来控制同时访问特定资源的线程数量,以此来达到协调线程工作。

b、维护了一个虚拟的资源池,如果许可为0则线程阻塞等待,直到许可大于0时又可以有机会获取许可了。

c、 内部也有公平锁、非公平锁来访问资源的静态内部类。

2、Semaphore方法

a、public Semaphore(int permits);// 创建一个给定许可数量的信号量对象,且默认以非公平锁方式获取资源

b、public Semaphore(int permits, boolean fair);//创建一个给定许可数量的信号量对象,且是否公平方式由传入的fair布尔参数值决定

c、public void acquire() ;//从此信号量获取一个许可,当许可数量小于零时,则阻塞等待

d、public void acquire(int permits) ;//从此信号量获取permits个许可,当许可数量小于零时,则阻塞等待,但是当阻塞等待的线程被唤醒后发现被中断过的话则会抛InterruptedException异常

e、public void acquireUninterruptibly(int permits) ;从此信号量获取permits个许可,当许可数量小于零时,则阻塞等待,但是当阻塞等待的线程被唤醒后发现被中断过的话则不会抛InterruptedException异常

f、public void release();//释放一个许可

g、public void release(int permits);释放permits个许可

以上只是列出主要方法名,方法详细解释,Semaphore类上面都有注释。就不一一累出来了。

举一个简单例子,帮助我们加深印象

/**

* @author shuliangzhao

* @Title: SemaPhoreTest

* @ProjectName design-parent

* @Description: TODO

* @date 2019/6/5 22:50

*/

public class SemaPhoreTest {

private Semaphore semaphore = new Semaphore(3);

class TaskThread implements Runnable{

private int id;

public TaskThread(int id) {

this.id = id;

}

@Override

public void run() {

try {

semaphore.acquire();

System.out.println("Thread " + id + " is working");

Thread.sleep(2000);

semaphore.release();

System.out.println("Thread " + id + " is over");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) {

SemaPhoreTest semaPhoreTest = new SemaPhoreTest();

/*for (int i = 0;i<6;i++) {

Thread thread = new Thread(semaPhoreTest.new TaskThread(i));

thread.start();

}*/

ExecutorService executorService = Executors.newCachedThreadPool();//同步队列线程

executorService.submit(semaPhoreTest.new TaskThread(1));

executorService.submit(semaPhoreTest.new TaskThread(2));

executorService.submit(semaPhoreTest.new TaskThread(3));

executorService.submit(semaPhoreTest.new TaskThread(4));

executorService.submit(semaPhoreTest.new TaskThread(5));

executorService.submit(semaPhoreTest.new TaskThread(6));

executorService.submit(semaPhoreTest.new TaskThread(7));

executorService.shutdown();

}

}

运行结果

format,png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值