package jaci.openrio.toast.core.thread; import jaci.openrio.toast.core.ToastConfiguration; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; /** * The Toast Asynchronous Thread Pool. This class acts as a task-scheduling system, in which tasks can be submitted for * work and will be completed when available. By default, the Thread Pool will launch 4 tasks at a time, and when each is * complete it will schedule the next. This can be changed in the Toast.conf file. * * Async Tasks have no guarantee for when they complete, and so this should be used for time-insensitive tasks. If you * rely on getting a return value or something similar of a Task, a Future is provided so you can 'wait' for the task to * be scheduled and finished. * * @author Jaci */ public class Async extends ThreadPoolExecutor { public static Async INSTANCE; /** * Start the main Async INSTANCE. This is done for you in Toast initialization. */ public static void init() { int size = ToastConfiguration.Property.THREAD_POOL_SIZE.asInt(); INSTANCE = new Async(size, size, "Toast|Async"); } /** * Create a new Async pool for you own usage * @param corePoolSize The starting size of the pool * @param maximumPoolSize The maximum size of the pool * @param name The name of the pool */ public Async(int corePoolSize, int maximumPoolSize, String name) { super(corePoolSize, maximumPoolSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new Factory(name)); } /** * Submit a task to this Async pool. Calls the {@link AsyncTask#onAddedToQueue(Async, Future)} method */ public Future submit(AsyncTask task) { Future f = submit((Runnable)task); task.onAddedToQueue(this, f); return f; } /** * Submit a task to the default Async pool. Calls the {@link AsyncTask#onAddedToQueue(Async, Future)} method */ public static Future schedule(AsyncTask task) { return INSTANCE.submit(task); } /** * Shutdown the thread pool and wait for any pending workers to finish. DO NOT CALL THIS ON THE MAIN THREAD POOL. */ public void finish() { shutdown(); } /** * Wait until the threadpool is done with all work, forever. DO NOT CALL THIS ON THE MAIN THREAD POOL. */ public void waitForCompletion() { try { awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); } catch (Exception e) {} } // Factory private static class Factory implements ThreadFactory { private AtomicInteger integer = new AtomicInteger(1); String name; public Factory(String name) { this.name = name; } /** * Creates a new Thread Object for the ThreadFactory. This is given the proper name for the Thread Pool and is not * set as a daemon to assure that it can be easily debugged in profilers and other utilities. */ @Override public Thread newThread(Runnable r) { Thread t = new Thread(r, name + "-" + integer.getAndIncrement()); if (t.isDaemon()) t.setDaemon(false); if (t.getPriority() != Thread.NORM_PRIORITY) t.setPriority(Thread.NORM_PRIORITY); return t; } } }