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

com.liferay.portal.kernel.concurrent.DefaultNoticeableFuture Maven / Gradle / Ivy

Go to download

Contains interfaces for the portal services. Interfaces are only loaded by the global class loader and are shared by all plugins.

There is a newer version: 149.0.0
Show newest version
/**
 * SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
 * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
 */

package com.liferay.portal.kernel.concurrent;

import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author Shuyang Zhou
 */
public class DefaultNoticeableFuture
	extends FutureTask implements NoticeableFuture {

	@SuppressWarnings("unchecked")
	public DefaultNoticeableFuture() {
		super((Callable)_emptyCallable);
	}

	public DefaultNoticeableFuture(Callable callable) {
		super(callable);
	}

	public DefaultNoticeableFuture(Runnable runnable, T result) {
		super(runnable, result);
	}

	@Override
	public boolean addFutureListener(FutureListener futureListener) {
		if (futureListener == null) {
			throw new NullPointerException("Future listener is null");
		}

		futureListener = new OnceFutureListener<>(futureListener);

		if (_futureListeners.add(futureListener)) {
			if (isDone()) {
				futureListener.complete(this);
			}

			return true;
		}

		return false;
	}

	@Override
	public boolean removeFutureListener(FutureListener futureListener) {
		if (futureListener == null) {
			throw new NullPointerException("Future listener is null");
		}

		return _futureListeners.remove(
			new OnceFutureListener(futureListener));
	}

	@Override
	public void set(T t) {
		super.set(t);
	}

	@Override
	public void setException(Throwable throwable) {
		super.setException(throwable);
	}

	@Override
	protected void done() {
		for (FutureListener futureListener : _futureListeners) {
			futureListener.complete(this);
		}
	}

	private static final Callable _emptyCallable =
		new Callable() {

			@Override
			public Object call() {
				return null;
			}

		};

	private final Set> _futureListeners =
		new CopyOnWriteArraySet<>();

	private static class OnceFutureListener implements FutureListener {

		public OnceFutureListener(FutureListener futureListener) {
			_futureListener = futureListener;
		}

		@Override
		public void complete(Future future) {
			if (_ran.compareAndSet(false, true)) {
				_futureListener.complete(future);
			}
		}

		@Override
		public boolean equals(Object object) {
			OnceFutureListener onceFutureListener =
				(OnceFutureListener)object;

			return _futureListener.equals(onceFutureListener._futureListener);
		}

		@Override
		public int hashCode() {
			return _futureListener.hashCode();
		}

		private final FutureListener _futureListener;
		private final AtomicBoolean _ran = new AtomicBoolean();

	}

}