java.util.concurrent.Semaphore
信号量是一种计数器,用来保护一个或者多个共享资源的访问,它是并发编程的一种基础工具。
信号量通过计数器的方式来对资源进行访问控制
当其计数器值大于0时,表示有资源可以访问
当其计数器值等于0时,线程将进入休眠状态直到计数器值大于0
通过信号量的构造函数指定资源数量:
private final Semaphore semaphore = new Semaphore(1);
表示该信号量的计数器值只能为0或者1,也称为二进制信号量
这样可以限制每次执行的线程只有一个
信号量的使用:
private final Semaphore semaphore = new Semaphore(1);
public void a() {
try {
//获取信号量的锁
semaphore.acquire();
//对共享资源进行操作
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放信号量
semaphore.release();
}
}
信号量也有对应的tryAcquire()方法,和Lock的tryLock()一样
使用信号量控制资源的多副本并发访问控制
<pre style="background-color: rgb(255, 255, 255); font-family: Consolas; font-size: 10.5pt;"><pre name="code" class="java">public class TestSemaphore {
//信号量控制资源的状态
private final Semaphore semaphore;
//资源数组,true表示可用(空闲)
private boolean[] resources;
//保护对资源数组的访问
private Lock lock;
//资源数量
private int resourceCount = 3;
public TestSemaphore() {
semaphore = new Semaphore(resourceCount);
resources = new boolean[resourceCount];
for (int i = 0; i < resourceCount; i++) {
resources[i] = true;
}
lock = new ReentrantLock();
}
public void doSth() {
try {
semaphore.acquire();
int resource = getResource();
//使用resource进行操作
//任务完成,把对应的resource置为空闲
resources[resource] = true;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放信号量
semaphore.release();
}
}
/**
* 获取空闲的资源
*
* @return 空闲的资源下标,没有就返回-1
*/
private int getResource() {
//资源下标
int ret = -1;
try {
lock.lock();
for (int i = 0; i < resources.length; i++) {
if (resources[i]) {
ret = i;
resources[i] = false;
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return ret;
}
}