/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.executor.internal;
import com.liferay.portal.kernel.concurrent.FutureListener;
import com.liferay.portal.kernel.concurrent.NoticeableFuture;
import com.liferay.portal.kernel.concurrent.ThreadPoolExecutor;
import com.liferay.portal.kernel.executor.PortalExecutorManager;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Future;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
/**
* @author Shuyang Zhou
*/
@Component(immediate = true, service = PortalExecutorManager.class)
public class PortalExecutorManagerImpl implements PortalExecutorManager {
@Override
public ThreadPoolExecutor getPortalExecutor(String name) {
return getPortalExecutor(name, true);
}
@Override
public ThreadPoolExecutor getPortalExecutor(
String name, boolean createIfAbsent) {
ThreadPoolExecutor threadPoolExecutor = _threadPoolExecutors.get(name);
if ((threadPoolExecutor == null) && createIfAbsent) {
threadPoolExecutor = _portalExecutorFactory.createPortalExecutor(
name);
ThreadPoolExecutor previousThreadPoolExecutor =
registerPortalExecutor(name, threadPoolExecutor);
if (previousThreadPoolExecutor != null) {
threadPoolExecutor.shutdown();
threadPoolExecutor = previousThreadPoolExecutor;
}
}
return threadPoolExecutor;
}
@Override
public ThreadPoolExecutor registerPortalExecutor(
String name, ThreadPoolExecutor threadPoolExecutor) {
ThreadPoolExecutor previousThreadPoolExecutor =
_threadPoolExecutors.putIfAbsent(name, threadPoolExecutor);
if (previousThreadPoolExecutor == null) {
NoticeableFuture<Void> terminationNoticeableFuture =
threadPoolExecutor.terminationNoticeableFuture();
terminationNoticeableFuture.addFutureListener(
new UnregisterFutureListener(name));
}
return previousThreadPoolExecutor;
}
@Reference(unbind = "-")
public void setPortalExecutorFactory(
PortalExecutorFactory portalExecutorFactory) {
_portalExecutorFactory = portalExecutorFactory;
}
@Override
public void shutdown() {
shutdown(false);
}
@Override
public void shutdown(boolean interrupt) {
for (ThreadPoolExecutor threadPoolExecutor :
_threadPoolExecutors.values()) {
if (interrupt) {
threadPoolExecutor.shutdownNow();
}
else {
threadPoolExecutor.shutdown();
}
}
}
@Deactivate
protected void deactivate() {
shutdown(true);
}
protected class UnregisterFutureListener implements FutureListener<Void> {
@Override
public void complete(Future<Void> future) {
_threadPoolExecutors.remove(name);
}
protected UnregisterFutureListener(String name) {
this.name = name;
}
protected final String name;
}
private PortalExecutorFactory _portalExecutorFactory;
private final ConcurrentMap<String, ThreadPoolExecutor>
_threadPoolExecutors = new ConcurrentHashMap<>();
}