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.