Java中的信号量
我的代码:Java中的信号量,java,semaphore,Java,Semaphore,我的代码: public class t3 { static int i = 1; public static void main(String[] args) throws InterruptedException { Semaphore sem = new Semaphore(1); sem.release(); System.out.println(i++); //1 then ++ sem.release(); System.out.pr
public class t3 {
static int i = 1;
public static void main(String[] args) throws InterruptedException {
Semaphore sem = new Semaphore(1);
sem.release();
System.out.println(i++); //1 then ++
sem.release();
System.out.println(i++); //2
sem.acquire();
System.out.println(i++); //3
sem.acquire();
System.out.println(i++); //4
sem.acquire();
System.out.println(i++); //5
sem.acquire();
System.out.println(i++); //6
sem.acquire();
System.out.println(i++); //7
}
}
我的输出:
1
2
3
4
5
为什么不是这样:
1
2
3
4
5
6
7
我猜许可证计数器是这样的:0,-1,-2,-1,0,1,然后阻塞。因为你有一个许可证。似乎许可证计数器的工作方式与此相反,它从1开始,然后像1、2、3、2、1、0和block那样运行。(谢谢@JB Nizet)信号量是权限池。一开始
Semaphore sem = new Semaphore(1)
仅包含一个权限,但由于您使用了两次release
,因此又添加了两个权限,因此它总共有3个权限。接下来,您调用了acquire
五次,但由于信号量中只有三个权限,第四次调用acquire
会让线程等待可用的权限
要更清楚地看到它,请查看此代码中的注释
Semaphore sem = new Semaphore(1); // 1 permission available
sem.release(); // 2 permissions available after this method
System.out.println(i++); // 1 then ++
sem.release(); // 3 permissions available after this method
System.out.println(i++); // 2
sem.acquire(); // 2 permissions available after this method
System.out.println(i++); // 3
sem.acquire(); // 1 permission available after this method
System.out.println(i++); // 4
sem.acquire(); // 0 permissions available after this method
System.out.println(i++); // 5
sem.acquire(); // now thread needs to wait for available permission
System.out.println(i++); // 6
sem.acquire();
System.out.println(i++); // 7
您应该注意到您的进程没有完成,它处于等待状态。
运行下面的代码版本,改变传递给信号量构造函数的初始值,您应该能够感受到这种行为。
您应该注意到,每次调用release()都会增加可用许可, 每次调用acquire()都会减小池的大小
public static void main(String[] args) throws InterruptedException {
Semaphore sem = new Semaphore(1);
sem.release();
System.out.println(sem.availablePermits() + ":" + i++); //1 then ++
sem.release();
System.out.println(sem.availablePermits() + ":" + i++); //2
sem.acquire();
System.out.println(sem.availablePermits() + ":" + i++); //3
sem.acquire();
System.out.println(sem.availablePermits() + ":" + i++); //4
sem.acquire();
System.out.println(sem.availablePermits() + ":" + i++); //5
sem.acquire();
System.out.println(sem.availablePermits() + ":" + i++); //6
sem.acquire();
System.out.println(sem.availablePermits() + ":" + i++); //7
}
}
@邹祖:我也不知道,但它就在这里:好吧,伙计们,我的坏:)我不知道它的存在。我不明白的是“信号量有什么不清楚?”:)这可以通过阅读信号量的javadoc来回答。它是另一种方式:1,2,3,2,1,0->阻塞。relase()添加一个许可证。acquire()获取一个许可证,并减少许可证或块(如果没有)的数量。