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

org.conqat.lib.commons.concurrent.ThreadUtils Maven / Gradle / Ivy

There is a newer version: 2024.7.2
Show newest version
/*
 * Copyright (c) CQSE GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.conqat.lib.commons.concurrent;

import java.time.Duration;
import java.util.function.BooleanSupplier;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.conqat.lib.commons.assertion.CCSMAssert;

/**
 * Utility methods for dealing with threads.
 */
public class ThreadUtils {

	/**
	 * Causes the current thread to sleep the given number of milliseconds. The sleep phase can also
	 * exit earlier if an {@link InterruptedException} is thrown. Any {@link InterruptedException} is
	 * silently discarded.
	 */
	public static void sleep(long milliseconds) {
		try {
			Thread.sleep(milliseconds);
		} catch (InterruptedException e) {
			// ignore exception
		}
	}

	/**
	 * Puts the thread to sleep but regularly polls for cancels using {@code cancelTokenSupplier} in
	 * case the caller issued a cancel request.
	 * 
	 * @param delay
	 *            complete duration to sleep
	 * @param pollingInterval
	 *            interval at which the {@code cancelTokenSupplier} should be queried
	 * @param cancelTokenSupplier
	 *            Supplier indicating whether the sleep should stop before the complete {@code delay}
	 *            finished
	 * @return Whether the complete {@code delay} was slept ({@code true}) or stopped by the
	 *         {@code cancelTokenSupplier} ({@code false})
	 */
	public static boolean cancelableSleep(@NonNull Duration delay, @NonNull Duration pollingInterval,
			@NonNull BooleanSupplier cancelTokenSupplier) throws InterruptedException {
		CCSMAssert.isNotNull(delay, () -> String.format("Expected \"%s\" to be not null", "delay"));
		CCSMAssert.isNotNull(pollingInterval, () -> String.format("Expected \"%s\" to be not null", "pollingInterval"));
		CCSMAssert.isNotNull(cancelTokenSupplier,
				() -> String.format("Expected \"%s\" to be not null", "cancelTokenSupplier"));
		if (delay.isZero() || delay.isNegative()) {
			throw new IllegalArgumentException("delay must be positive");
		}
		if (pollingInterval.isZero() || pollingInterval.isNegative()) {
			throw new IllegalArgumentException("pollingInterval must be positive");
		}

		for (Duration remainingDelay = delay; !remainingDelay.isZero()
				&& !remainingDelay.isNegative(); remainingDelay = remainingDelay.minus(pollingInterval)) {
			if (remainingDelay.compareTo(pollingInterval) < 0) {
				sleep(remainingDelay);
			} else {
				sleep(pollingInterval);
			}
			if (cancelTokenSupplier.getAsBoolean()) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Same as {@link Thread#sleep(long)}, but converts the given duration to millis.
	 *
	 * @see Thread#sleep(long)
	 */
	public static void sleep(Duration duration) throws InterruptedException {
		Thread.sleep(duration.toMillis());
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy