I need a semaphore with the following features:
- it should be non-blocking, i.e. if the thread cannot get the permit
it should go further without waiting - it should be nonreentrant, i.e. if the same thread enters the
guarded piece of code twice it should take away two permits instead of
one
I have written the following code:
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();
}
}
Another option is this Semaphore:
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();
}
}
Are the both implementations thread-safe and correct?
Which one is better?
How would you go about this task?
Doesn’t
java.util.concurrent.Semaphorealready do all that?It has a
tryAcquirefor non-blocking acquire, and it maintains a simple count of remaining permits (of which the same thread could take out more than one).