我需要一个具有以下功能的信号量:
- 它应该是非阻塞的,即如果线程无法获得许可,它应该更进一步而无需等待
- 它应该是不可重入的,即如果同一个线程两次进入受保护的代码段,它应该带走两个许可而不是一个
我写了以下代码:
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();
}
}
这两种实现都是线程安全且正确的吗?哪一个更好?你将如何完成这项任务?