我需要一个具有以下功能的信号量:
我写了以下代码:
public class SimpleSemaphore
{
private int permits;
private AtomicLong counter = new AtomicLong();
SimpleSemaphore(int permits)
{
this.permits = permits;
}
boolean acquire()
{
if (counter.incrementAndGet() < permits)
{
return true;
}
else
{
counter.decrementAndGet();
return false;
}
}
void release()
{
counter.decrementAndGet();
}
}
另一种选择是这个信号量:
public class EasySemaphore
{
private int permits;
private AtomicLong counter = new AtomicLong();
EasySemaphore(int permits)
{
this.permits = permits;
}
boolean acquire()
{
long index = counter.get();
if (index < permits)
{
if (counter.compareAndSet(index, index + 1))
{
return true;
}
}
return false;
}
void release()
{
counter.decrementAndGet();
}
}
这两个实现是否是线程安全且正确的? 哪一个更好? 你会怎么做这个任务?
答案 0 :(得分:7)
java.util.concurrent.Semaphore
是不是已经完成了所有这些?
它具有tryAcquire
非阻塞获取,并且它保留了剩余许可的简单计数(其中相同的线程可以取出多个)。
答案 1 :(得分:0)
我会说第二个更好,因为计数器永远不会大于0(并且效率稍高)
我会使用一个循环,否则当剩下许可证时你可以让方法失败。
public class EasySemaphore {
private final AtomicInteger counter;
EasySemaphore(int permits) {
counter = new AtomicInteger(permits);
}
boolean acquire() {
// highly unlikely to loop more than once.
while(true) {
int count = counter.get();
if (count <= 0) return false;
if (counter.compareAndSet(count, count -1))
return true;
}
}
void release() {
counter.incrementAndGet();
}
}