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.