java 信号量如何以及为什么会发出比初始化时更多的许可?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7554839/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How and why can a Semaphore give out more permits than it was initialized with?
提问by Vinoth Kumar C M
I am reading the book Java Concurrency in Practice. In a section about java.util.concurrent.Semaphore
, the below lines are present in the book. It is a comment about its implementation of "virtual permit" objects
我正在阅读 Java 并发实践这本书。在关于 的一节java.util.concurrent.Semaphore
中,书中出现了以下几行。它是关于其实现“虚拟许可”对象的评论
The implementation has no actual permit objects, and
Semaphore
does not associate dispensed permits with threads, so a permit acquired in one thread can be released from another thread. You can think ofacquire
as consuming a permit andrelease
as creating one; aSemaphore
is not limited to the number of permits it was created with.
该实现没有实际的许可对象,
Semaphore
也没有将分配的许可与线程相关联,因此在一个线程中获得的许可可以从另一个线程中释放。您可以将其acquire
视为使用许可和release
创建许可;aSemaphore
不限于创建时使用的许可数量。
Can somebody explain this? I am having trouble understanding this. If we create a pool of fixed size, we create a fixed number of "permits". From the above statement, it looks like the "permits" can keep growing. Why is it designed this way?
有人可以解释一下吗?我很难理解这一点。如果我们创建一个固定大小的池,我们就会创建一个固定数量的“许可”。从上面的说法来看,“许可证”似乎可以继续增长。为什么要这样设计?
采纳答案by Thilo
Instead of "handing out" permit objects, the implementation just has a counter. When a new permit is "created" the counter is increased, when a permit is "returned" the counter is decreased.
实现只是有一个计数器,而不是“分发”许可对象。当“创建”新许可时,计数器增加,当“返回”许可时,计数器减少。
This makes for much better performance than creating actual objects all the time.
这比一直创建实际对象的性能要好得多。
The tradeoff is that the Semaphore itself cannot detect certain kinds of programming errors (such as unauthorized permit cash-ins, or semaphore leaks). As the coder, you have to make sure to follow the rules on your own.
权衡是信号量本身无法检测某些类型的编程错误(例如未经授权的许可兑现或信号量泄漏)。作为编码员,您必须确保自己遵守规则。
回答by Peter Lawrey
Can somebody explain this ? From the above statement, it looks like the "permits" can keep growing.
有人可以解释一下吗?从上面的说法来看,“许可证”似乎可以继续增长。
A semaphore is a counter of permits. acquire is like decrement which waits rather than go below zero. It has no upper limit.
信号量是许可的计数器。获取就像递减,它等待而不是低于零。它没有上限。
Why is it designed this way ?
为什么这样设计?
Because its simple to do so.
因为这样做很简单。
回答by lxl
I think that it means the times what we may require Semaphore as the times we released "extra" and plus the permits it created with.
我认为这意味着我们可能需要 Semaphore 的时间作为我们发布“额外”的时间以及它创建的许可。
Such as:
如:
Semaphore s = new Semaphore(1); // one permit when initialize
s.acquire();
s.release();
s.release(); // "extra" release.
At this moment, this semaphore allows one permit originally and one "extra" permit
此时,该信号量允许一个原始许可和一个“额外”许可
回答by Sunil
As mentioned in first post "Semaphore is not limited to the number of permits it was created with"
正如第一篇文章中提到的“信号量不限于它创建的许可数量”
Every call to .release() API will increase the permit count by one. So Semaphores doesn't have a fixed permit size
每次调用 .release() API 都会将许可计数增加一。所以信号量没有固定的许可大小
回答by Tim Williscroft
It is surprising to some of us.
这对我们中的一些人来说是令人惊讶的。
You can easily subclass up a bounded semaphore.
您可以轻松地对有界信号量进行子类化。
/**
* Terrible performance bounded semaphore.
**/
public class BoundedSemaphore extends Semaphore {
private static final long serialVersionUID = -570124236163243243L;
final int bound;
public BoundedSemaphore(int permits) {
super(permits);
bound=permits;
}
@Override
synchronized public void acquire() throws InterruptedException {
super.acquire();
}
@Override
synchronized public boolean tryAcquire() {
return super.tryAcquire();
}
@Override
synchronized public void release() {
if( availablePermits()<bound){
super.release();
}
}
@Override
synchronized public void acquire(int count) throws InterruptedException {
super.acquire(count);
}
@Override
synchronized public boolean tryAcquire(int count) {
return super.tryAcquire(count);
}
@Override
synchronized public void release(int count) {
if( availablePermits()<bound){
super.release(bound-availablePermits());
}
}
}
回答by Bhaskar
Perhaps the last line " a Semaphore is not limited to the number of permits it was created with" is your source of confusion.
也许最后一行“信号量不限于创建它的许可数量”是您混淆的根源。
A semaphore when created is initialized with a fixed set of permits. This then becomes the maximum number of permits that the semaphore can simultaneuosly dispense at any time during the life time of that semaphore. You cannotdynamically increase this number except by re-initializing the semaphore .
信号量在创建时使用一组固定的许可进行初始化。这将成为该信号量在该信号量的生命周期内的任何时间可以同时分配的最大许可数。除非重新初始化 semaphore ,否则您无法动态增加此数字。
The meaning if the quoted line ( from JCIP ) is this : First , the semantics of how a semaphore works is not limited to the details of issuing and regaining a permit - this is manifested in the fact that any thread can that has access the semaphore can have a permit released ( even though this thread did not own the permit at the first place)
引用的行(来自 JCIP)的含义是:首先,信号量如何工作的语义不限于颁发和重新获得许可的细节——这体现在任何线程都可以访问信号量的事实中。可以释放许可证(即使此线程最初不拥有许可证)
Second , you can dynamically reduce the maximum permits of a semaphore - by calling reducePermits(int)
method.
其次,您可以通过调用reducePermits(int)
方法动态减少信号量的最大许可。