我正在编写一个测试代码,我发现如果我们在release()
之前放置acquire()
,那么Binary Semaphore功能就会被破坏。
我检查过并发现多个线程通过acquire()
并将计数增加到N,其中N是线程数,因此与二进制信号量相矛盾。
import java.util.concurrent.Semaphore;
/**
* Consider an ATM cubicle with 1 ATM, Semaphore can make sure only 1 person
* can access simultaneously.
*
* Here if relese() comes before then this binary semaphore is not working.
*/
public class SemaphoreTest {
// max 4 people
static Semaphore semaphore = new Semaphore(1);
public static void main(String[] args) {
System.out.println("Total available Semaphore permits : " + semaphore.availablePermits());
MyATMThread t1 = new MyATMThread("A",semaphore);
t1.start();
MyATMThread t2 = new MyATMThread("B",semaphore);
t2.start();
MyATMThread t3 = new MyATMThread("C",semaphore);
t3.start();
MyATMThread t4 = new MyATMThread("D",semaphore);
t4.start();
MyATMThread t5 = new MyATMThread("E",semaphore);
t5.start();
MyATMThread t6 = new MyATMThread("F",semaphore);
t6.start();
}
}
class MyATMThread extends Thread {
String name = "";
Semaphore semaphore = null;
MyATMThread(String name,Semaphore s) {
this.name = name;
this.semaphore=s;
}
public void run() {
try {
System.out.println(name + " : acquiring lock...");
System.out.println(name + " : available Semaphore permits now: " + semaphore.availablePermits());
semaphore.release();
semaphore.acquire();
System.out.println(name + " : got the permit!");
try {
for (int i = 1; i <= 5; i++) {
System.out.println(name + " : is performing operation " + i + ", available Semaphore permits : "
+ semaphore.availablePermits());
// sleep 1 second
Thread.sleep(1000);
}
} finally {
// calling release() after a successful acquire()
System.out.println(name + " : releasing lock...");
semaphore.release();
System.out.println(name + " : available Semaphore permits now: " + semaphore.availablePermits());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
有人可以解释这种行为吗?
答案 0 :(得分:2)
是的,你通过在获得之前释放(增加许可证)来编写破碎的代码(至少按照你的期望)。这是完全有效的,但如果您打算申请一个许可,则不应在release()
之前致电acquire()
来增加许可。
Semaphore
允许您将许可超出初始金额。这可以用于例如限制。工作线程将执行acquire()/release()
,并且节流器将根据某些逻辑减少/增加许可。
答案 1 :(得分:1)
release()方法用于增加许可证,因为来自docs:
不要求发布许可证的线程必须 通过致电收购获得该许可。正确使用一个 信号量是通过应用程序中的编程约定建立的。
换句话说:
semaphore.release(10),将在现有许可证上增加10个许可证
答案 2 :(得分:0)
您可以将release()
视为&#34;创建&#34;如果该线程之前未从该Semaphore
获得许可,则另一个许可。