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

net.therore.concurrent.SelfTuningExecutors Maven / Gradle / Ivy

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 net.therore.concurrent;

import java.lang.management.ManagementFactory;
import java.util.Hashtable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;

/**
 * @author [email protected]
 */
public class SelfTuningExecutors implements SelfTuningExecutorsMBean {

	static public final String MBEAN_DOMAIN = "net.therore.concurrent";

	static public final long DEFAULT_KEEP_ALIVE_SECONDS = 86400L;
	
	static volatile private SelfTuningExecutors defaultSelfTuningExecutors = null;
	
	private ThreadPoolExecutor coreExecutorService;
	
	private int defaultQueueSize = 100;

	private AtomicInteger totalPriority = new AtomicInteger(0);

	private CopyOnWriteArrayList executorServices = new CopyOnWriteArrayList();

	private final MBeanServer mbs;
	
	static public SelfTuningExecutors defaultSelfTuningExecutors() {
		if (defaultSelfTuningExecutors==null) {
			synchronized (SelfTuningExecutors.class) {
				if (defaultSelfTuningExecutors==null) {
					defaultSelfTuningExecutors = new SelfTuningExecutors("default", DEFAULT_KEEP_ALIVE_SECONDS);
				}
			}
		}
		return defaultSelfTuningExecutors;
	}
	
	public SelfTuningExecutors() {
		this(DEFAULT_KEEP_ALIVE_SECONDS);
	}

	public SelfTuningExecutors(String name, long keepAliveSeconds) {
		super();
		coreExecutorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
				keepAliveSeconds, TimeUnit.SECONDS,
                new SynchronousQueue());
		
        this.mbs = ManagementFactory.getPlatformMBeanServer();
        registerMBean(MBEAN_DOMAIN, "SelfTuningExecutors", null, name, this);
	}

	public SelfTuningExecutors(long keepAliveSeconds) {
		super();
		coreExecutorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
				keepAliveSeconds, TimeUnit.SECONDS,
                new SynchronousQueue());
		
        this.mbs = ManagementFactory.getPlatformMBeanServer();
        registerMBean(MBEAN_DOMAIN, "SelfTuningExecutors", null, String.valueOf(System.identityHashCode(this)), this);
	}
	
	public SelfTuningExecutors(String name) {
		super();
		coreExecutorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
				DEFAULT_KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
                new SynchronousQueue());
		
        this.mbs = ManagementFactory.getPlatformMBeanServer();
        registerMBean(MBEAN_DOMAIN, "SelfTuningExecutors", null, name, this);
	}

	private void registerMBean(String domain, String component, String clazz, String object, Object mbean) {
		try {
			Hashtable properties = new Hashtable();
			if (object!=null && !object.isEmpty())
				properties.put("context", object);
			if (component!=null && !component.isEmpty())
				properties.put("type", component);
			if (clazz!=null && !clazz.isEmpty())
				properties.put("name", clazz);
			mbs.registerMBean(mbean, new ObjectName(domain, properties));
		} catch (InstanceAlreadyExistsException e) {
			throw new RuntimeException(e);
		} catch (MBeanRegistrationException e) {
			throw new RuntimeException(e);
		} catch (NotCompliantMBeanException e) {
			throw new RuntimeException(e);
		} catch (MalformedObjectNameException e) {
			throw new RuntimeException(e);
		} catch (NullPointerException e) {
			throw new RuntimeException(e);
		} 
	}

	
	@Override
	public int getDefaultQueueSize() {
		return defaultQueueSize;
	}

	@Override
	public void setDefaultQueueSize(int defaultQueueSize) {
		this.defaultQueueSize = defaultQueueSize;
	}

	@Override
	public int getTotalPriority() {
		return totalPriority.get();
	}

	@Override
	public int getPoolSize() {
		int result = 0;
		for (SelfTuningExecutorService service : executorServices)
			result += service.getPoolSize();
		return result;	
	}

	public SelfTuningExecutorService newSelfTuningExecutor(int corePoolSize, int initPoolSize, int maximumPoolSize) {
		return newSelfTuningExecutor(corePoolSize, initPoolSize, maximumPoolSize, maximumPoolSize, defaultQueueSize);
	}

	public SelfTuningExecutorService newSelfTuningExecutor(String name, int corePoolSize, int initPoolSize, int maximumPoolSize) {
		return newSelfTuningExecutor(name, corePoolSize, initPoolSize, maximumPoolSize, maximumPoolSize, defaultQueueSize);
	}

	public SelfTuningExecutorService newSelfTuningExecutor(int corePoolSize, int initPoolSize, int maximumPoolSize, int priority, int queueSize) {
		totalPriority.addAndGet(priority);
		SelfTuningExecutorService executorService = new SelfTuningExecutorService(this, coreExecutorService, null, corePoolSize, initPoolSize, maximumPoolSize, priority, queueSize);
		executorServices.add(executorService);
		registerMBean(MBEAN_DOMAIN, "SelfTuningExecutors", "ExecutorService", executorService.getName(), executorService);
		return executorService;
	}
	
	public SelfTuningExecutorService newSelfTuningExecutor(String name, int corePoolSize, int initPoolSize, int maximumPoolSize, int priority, int queueSize) {
		totalPriority.addAndGet(priority);
		SelfTuningExecutorService executorService;
		executorServices.add(executorService = new SelfTuningExecutorService(this, coreExecutorService, name, corePoolSize, initPoolSize, maximumPoolSize, priority, queueSize));
		registerMBean(MBEAN_DOMAIN, "SelfTuningExecutors", "ExecutorService", name, executorService);
		return executorService;
	}

	@Override
	public boolean isShutdown() {
		return coreExecutorService.isShutdown();
	}

	@Override
	public boolean isTerminated() {
		return coreExecutorService.isShutdown();
	}

	@Override
	public boolean isTerminating() {
		return coreExecutorService.isTerminating();
	}

	public void shutDown() {
		this.coreExecutorService.shutdown();
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy