Token bucket rate limiter with a refill clock

Kotlin
import kotlin.math.min

class TokenBucket(
    private val capacity: Double,
    private val refillPerSecond: Double,
) {
    private var tokens = capacity
    private var last = System.currentTimeMillis()

    @Synchronized
    fun tryAcquire(cost: Double = 1.0): Boolean {
        val now = System.currentTimeMillis()
        tokens = min(capacity, tokens + (now - last) / 1000.0 * refillPerSecond)
        last = now
        if (tokens < cost) return false
        tokens -= cost
        return true
    }
}

val bucket = TokenBucket(5.0, 1.0)
check(bucket.tryAcquire() && !bucket.tryAcquire(5.0))