Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to decrement one field and increment another field atomically in java using concurrency classes

I have a state machine - pending and completed - AtomicLong (threaded). I need to decrement pending and increment completed in an atomic fashion

private final AtomicLong pending = new AtomicLong();
private final AtomicLong completed = new AtomicLong();

void markComplete() {
  this.pending.decrementAndGet();
  this.completed.incrementAndGet();
}

I can make this atomic by synchronising using a block. But that seems to defeat the use of using concurrent objects.

synchronized void markComplete() {
  this.pending.decrementAndGet();
  this.completed.incrementAndGet();
}

I wish to know if there is a niftier way of doing this?

Thanks for helping me.

like image 793
SudhirR Avatar asked Dec 10 '25 15:12

SudhirR


1 Answers

If pending and complete fit into the int range (and as long as pending is greater than zero when you call markComplete()) you could do something along these lines:

private final AtomicLong pendingAndComplete = new AtomicLong();

void markComplete() {
  this.pendingAndComplete.addAndGet(1L<<32-1); // this is atomic
}
void markPending() {
  this.pendingAndComplete.incrementAndGet(); // this is atomic
}

void doSomething() {
  long current = this.pendingAndComplete.get(); // this fetches the current state atomically

  int currentCompleted = (int)(current >> 32);
  int currentPending = (int) current;
}
like image 183
Thomas Kläger Avatar answered Dec 14 '25 16:12

Thomas Kläger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!