All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.akurilov.commons.concurrent.RateThrottle Maven / Gradle / Ivy

There is a newer version: 2.3.6
Show newest version
package com.github.akurilov.commons.concurrent;

import java.util.concurrent.TimeUnit;

import static java.lang.System.nanoTime;

/**
 * A semaphore-like non-blocking throttle which permits at the given rate.
 */
public final class RateThrottle
implements Throttle {

	private final long periodNanos;
	private volatile long startTime = -1;
	private volatile long acquiredCount = 0;

	/**
	 * @param rateLimit The rate (permits/sec) limit for the permits
	 */
	public RateThrottle(final double rateLimit) {
		if(rateLimit <= 0) {
			throw new IllegalArgumentException(
				"Rate limit should be more than 0, but got " + rateLimit
			);
		}
		periodNanos = (long) (TimeUnit.SECONDS.toNanos(1) / rateLimit);
	}

	@Override
	public final boolean tryAcquire(final X item) {
		synchronized(this) {
			if(startTime > 0) {
				final long periodCount = (nanoTime() - startTime) / periodNanos;
				if(periodCount > acquiredCount) {
					acquiredCount ++;
					return true;
				} else {
					return false;
				}
			} else {
				startTime = nanoTime();
				acquiredCount ++;
				return true;
			}
		}
	}
	
	@Override
	public final int tryAcquire(final X item, final int requiredCount) {
		synchronized(this) {
			if(startTime > 0) {
				final int availableCount = (int) (
					(nanoTime() - startTime) / periodNanos - acquiredCount
				);
				if(availableCount > requiredCount) {
					acquiredCount += requiredCount;
					return requiredCount;
				} else {
					acquiredCount += availableCount;
					return availableCount;
				}
			} else {
				startTime = nanoTime();
				acquiredCount += requiredCount;
				return requiredCount;
			}
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy