package com.laytonsmith.PureUtilities; import com.laytonsmith.PureUtilities.Common.StreamUtils; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; /** * Creates a new queue * */ public class RunnableQueue { private ExecutorService service; private static int threadCount = 0; private ThreadFactory threadFactory; public RunnableQueue(String threadPrefix){ this(threadPrefix, null); } public RunnableQueue(final String threadPrefix, final Thread.UncaughtExceptionHandler exceptionHandler){ if(threadPrefix == null){ throw new NullPointerException(); } threadFactory = new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread t = new Thread(r, threadPrefix + "-" + (++threadCount)); t.setDaemon(false); if(exceptionHandler != null){ t.setUncaughtExceptionHandler(exceptionHandler); } else { t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { StreamUtils.GetSystemErr().println("The thread " + t.getName() + " threw an exception, and it was not handled."); e.printStackTrace(StreamUtils.GetSystemErr()); } }); } return t; } }; } private void activate(){ if(service == null){ service = Executors.newSingleThreadExecutor(threadFactory); } } /** * Schedules a runnable to run whenever the queue pump can get to it. Returns * immediately. * @param r */ public void invokeLater(final DaemonManager dm, final Runnable r){ if(dm != null){ dm.activateThread(null); } activate(); service.submit(new Runnable() { @Override public void run() { try{ r.run(); } finally { if(dm != null){ dm.deactivateThread(null); } } } }); } public <T> T invokeAndWait(Callable<T> callable) throws InterruptedException, ExecutionException{ activate(); return service.submit(callable).get(); } public void shutdown() { activate(); service.shutdownNow(); } }