CAS Pattern
Compare and set pattern
For example, consider the following
class RateLimiter {
private int capacity;
public RateLimiter(int capacity) {
this.capacity = capacity;
}
public accept(Request request) {
if (this.capacity == 0) return false;
this.capacity -= 1;
return true;
}
}
If we want to make this class thread safe, we have to follow this pattern:
class RateLimiter {
private AtomicInteger capacity;
public RateLimiter(int capacity) {
this.capacity = new AtomicInteger(capacity);
}
public accept(Request request) {
int currentCapacity;
do {
currentCapacity = this.capacity.get();
if (currentCapacity == 0) return false;
} while (!this.capacity.compareAndSet(currentCapacity, currentCapacity - 1))
return true;
}
}
So basically if this.capacity is not currentCapacity, we will keep rerun the above with currentCapacity updated to the new value and handle the logic with the new updated value.
If the currentCapacity == 0 at that moment, we check if (currentCapacity == 0) instead of if (this.capacity.get() == 0) because the currentCapacity is the value of the current request, if we do if (this.capacity.get() == 0) it might not be 0 anymore because of another request take over.