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

net.sf.extcos.internal.ThreadManager Maven / Gradle / Ivy

package net.sf.extcos.internal;

import static net.sf.extcos.util.Assert.iae;
import static net.sf.extcos.util.Assert.ise;
import static net.sf.extcos.util.StringUtils.append;

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;

import net.sf.extcos.util.Assert;

public class ThreadManager {
	private static ThreadManager instance;

	private final AtomicInteger registered = new AtomicInteger();
	private final AtomicInteger invoked = new AtomicInteger();
	private final AtomicInteger finished = new AtomicInteger();
	private ThreadPoolExecutor executor;
	private final Object sync = new Object();

	private ThreadManager() {
	}

	public static ThreadManager getInstance() {
		if (instance == null) {
			instance = new ThreadManager();
		}

		return instance;
	}

	public void register() {
		registered.incrementAndGet();
	}

	public void invoke(final Runnable runnable) {
		Assert.isTrue(invoked.get() < registered.get(), ise());
		Assert.notNull(runnable, iae());

		invoked.incrementAndGet();
		if (invoked.get() == 1) {			// if root filter interceptor invoked
			invokeBlocking(runnable);
		} else {							// if matching filter interceptor invoked
			invokeNonBlocking(runnable);
		}
	}

	private void invokeBlocking(final Runnable runnable) {
		Thread t = new Thread(runnable, append("eXtcos managed thread ", invoked));
		t.setDaemon(true);
		t.start();

		while (t.isAlive()) {
			try {
				t.join();
			} catch (InterruptedException ignored) { /* ignored */ }
		}

		finished.incrementAndGet();

		while (finished.get() < registered.get()) {
			try {
				synchronized (sync) {
					sync.wait();
				}
			} catch (InterruptedException ignored) { /* ignored */ }
		}

		if (executor != null) {			// if returning all without storing any there's no executor
			executor.shutdownNow();
		}
	}

	private void invokeNonBlocking(final Runnable runnable) {
		getExecutor().execute(new Runnable() {
			@Override
			public void run() {
				runnable.run();
				finished.incrementAndGet();

				synchronized (sync) {
					sync.notify();
				}
			}
		});
	}

	// for lazy initialization
	private ThreadPoolExecutor getExecutor() {
		if (executor == null) {
			executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
			executor.setCorePoolSize(5 > registered.get() ? registered.get() : 5);
			executor.setMaximumPoolSize(10);
			executor.setThreadFactory(new ThreadFactory() {
				private ThreadGroup threadGroup;

				@Override
				public Thread newThread(final Runnable runnable) {
					Thread thread = new Thread(getThreadGroup(), runnable, append("eXtcos managed thread ", getInvoked()));
					thread.setDaemon(true);
					return thread;
				}

				private ThreadGroup getThreadGroup() {
					if (threadGroup == null) {
						threadGroup = new ThreadGroup("eXtcos Thread Group");
						threadGroup.setDaemon(true);
					}

					return threadGroup;
				}
			});
			executor.prestartCoreThread();
		}

		return executor;
	}

	private int getInvoked() {
		return invoked.get();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy