У меня есть ситуация, когда у меня есть обратный вызов, который я хочу выполнить один раз.В качестве аргумента, скажем, это выглядит так:
final X once = new X(1);
Runnable r = new Runnable() {
@Override public void run() {
if (once.use())
doSomething();
}
}
, где X - некоторый параллельный объект со следующим поведением:
конструктор: X (int N) - выделяет N разрешений на использование
boolean use()
: если существует хотя бы одно разрешение на использование, используйте одно из них и верните true.В противном случае верните false.Эта операция является атомарной по отношению к нескольким потокам.
Я знаю, что могу использовать java.util.concurrent.Semaphore , но мне не нуженблокирование / ожидание этого, и я хочу, чтобы это было одноразовое использование.
AtomicInteger не выглядит достаточно, если я не делаю что-то вроде
class NTimeUse {
final private AtomicInteger count;
public NTimeUse(int N) { this.count = new AtomicInteger(N); }
public boolean use() {
while (true)
{
int n = this.count.get();
if (n == 0)
return false;
if (this.count.compareAndSet(n, n-1))
return true;
}
}
и я чувствую тошнотуо цикле while.
CountDownLatch не будет работать, потому что метод countDown () не имеет возвращаемого значения и не может быть выполнен атомарно w / r / t getCount ().
Должен ли я просто использовать семафор или есть более подходящий класс?