package com.laytonsmith.PureUtilities; import java.util.HashSet; import java.util.Set; /** * A daemon manager allows for a layer on top of Java threads to determine * if there are any threads open that are actually doing any processing. * This allows for a thread to wait for all spinoff threads before exiting, whether * or not those threads are daemon threads or not. All the methods in this class * are threadsafe. */ public class DaemonManager { private final Object lock = new Object(); private final Set<Thread> threads = new HashSet<>(); private int count = 0; /** * Sets a thread to "daemon" mode, meaning it is currently * active. Null may be sent, in which case the current thread * is used. You should * always put a deactivateThread call for every activateThread call. * @param t The thread to activate */ public void activateThread(Thread t){ synchronized(lock){ if(t != null){ threads.add(t); } else { threads.add(Thread.currentThread()); } ++count; } } /** * Sets a thread to "non daemon" mode, meaning it is currently * inactive. If null, the current thread is used. * @param t The thread to deactivate */ public void deactivateThread(Thread t){ synchronized(lock){ if(t != null){ threads.remove(t); } else { threads.remove(Thread.currentThread()); } --count; lock.notify(); } } /** * Returns an array of all active threads. * @return */ public Thread[] getActiveThreads(){ synchronized(lock){ return threads.toArray(new Thread[threads.size()]); } } /** * Waits for all threads to finish, then returns. * @throws InterruptedException */ public void waitForThreads() throws InterruptedException{ synchronized(lock){ while(count > 0){ lock.wait(); } } } }