如何从多个信号量之一获取许可?
How to acquire permits from one of multiple semaphores?
我有多个资源,每个资源都由自己的信号量控制。我想获取这些资源中的任何一个并持有它的信号量。这就像 acquire 上的 OR 操作:"acquire M permits from semaphore1 or semaphore2 or ... or semaphoreN." 明确地说,所有 M 个许可必须恰好从一个信号量中获取。
我想我想要一个方法 acquire
如下所示:
Semaphore acquiredSemaphore = acquire(4, semaphore1, semaphore2, semaphore3);
它应该等待(或 return 立即)直到它从任何信号量获得许可,并且它应该 return 信号量(这样我可以稍后释放许可)。我愿意使用方法、class 或设计模式的任意组合。
虽然没有测试:
Semaphore acquire(int permits, Semaphore ... semaphores) throws InterruptedException {
Semaphore candidate = null;
while (true) { // polling loop
for (Semaphore semaphore: semaphores) {
// attempt to aquire from next Semaphore in the list
if (semaphore.tryAcquire(permits) {
return semaphore;
}
// choose the candidate semaphore with maximum available permits
if (candidate == null || candidate.availablePermits < semaphore.availablePermits) {
candidate = semaphore;
}
}
// now we have to wait some time
// instead of plain sleeping, we wait on the most filled semaphore
if (candidate.tryAcquire(permits, 10, TimeUnit.MILLISECONDS) {
return semaphore;
}
}
}
我有多个资源,每个资源都由自己的信号量控制。我想获取这些资源中的任何一个并持有它的信号量。这就像 acquire 上的 OR 操作:"acquire M permits from semaphore1 or semaphore2 or ... or semaphoreN." 明确地说,所有 M 个许可必须恰好从一个信号量中获取。
我想我想要一个方法 acquire
如下所示:
Semaphore acquiredSemaphore = acquire(4, semaphore1, semaphore2, semaphore3);
它应该等待(或 return 立即)直到它从任何信号量获得许可,并且它应该 return 信号量(这样我可以稍后释放许可)。我愿意使用方法、class 或设计模式的任意组合。
虽然没有测试:
Semaphore acquire(int permits, Semaphore ... semaphores) throws InterruptedException {
Semaphore candidate = null;
while (true) { // polling loop
for (Semaphore semaphore: semaphores) {
// attempt to aquire from next Semaphore in the list
if (semaphore.tryAcquire(permits) {
return semaphore;
}
// choose the candidate semaphore with maximum available permits
if (candidate == null || candidate.availablePermits < semaphore.availablePermits) {
candidate = semaphore;
}
}
// now we have to wait some time
// instead of plain sleeping, we wait on the most filled semaphore
if (candidate.tryAcquire(permits, 10, TimeUnit.MILLISECONDS) {
return semaphore;
}
}
}