package at.favre.lib.dali.builder; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import at.favre.lib.dali.Dali; import at.favre.lib.dali.builder.blur.BlurWorker; import at.favre.lib.dali.util.BuilderUtil; /** * Created by PatrickF on 31.05.2014. */ public class ExecutorManager { private static final int MAX_QUEUE = 25; public enum ThreadPoolType {SERIAL, CONCURRENT} private ThreadPoolExecutor serialThreadPool; private ThreadPoolExecutor concurrentThreadPool; private ThreadPoolExecutor fireAndForgetThreadPool; private Map<String,List<Future<BlurWorker.Result>>> taskList; public ExecutorManager(int maxConcurrentMainWorkers) { concurrentThreadPool = new ThreadPoolExecutor(maxConcurrentMainWorkers, maxConcurrentMainWorkers,5000L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(MAX_QUEUE)); concurrentThreadPool.allowCoreThreadTimeOut(true); serialThreadPool = new ThreadPoolExecutor(1,1,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(MAX_QUEUE)); fireAndForgetThreadPool = new ThreadPoolExecutor(4, 4,5000L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(MAX_QUEUE)); fireAndForgetThreadPool.allowCoreThreadTimeOut(true); taskList = new ConcurrentHashMap<String, List<Future<BlurWorker.Result>>>(); } public Future<BlurWorker.Result> submitThreadPool(Callable<BlurWorker.Result> callable, String tag, ThreadPoolType type) { Future<BlurWorker.Result> future=null; if(type.equals(ThreadPoolType.CONCURRENT)) { future = concurrentThreadPool.submit(callable); } else { future = serialThreadPool.submit(callable); } if(!taskList.containsKey(tag)) { taskList.put(tag,new ArrayList<Future<BlurWorker.Result>>()); } taskList.get(tag).add(future); removeDoneTasks(); return future; } /** * Cancel all task with this tag and returns the canceled task count * @param tagToCancel * @return */ public synchronized int cancelByTag(String tagToCancel) { int i = 0; if(taskList.containsKey(tagToCancel)) { removeDoneTasks(); for (Future<BlurWorker.Result> future : taskList.get(tagToCancel)) { BuilderUtil.logVerbose(Dali.getConfig().logTag,"Canceling task with tag "+tagToCancel,Dali.getConfig().debugMode); future.cancel(true); i++; } //remove all canceled tasks Iterator<Future<BlurWorker.Result>> iter = taskList.get(tagToCancel).iterator(); while (iter.hasNext()) { if (iter.next().isCancelled()) { iter.remove(); } } } return i; } private void removeDoneTasks() { for (String tag : taskList.keySet()) { Iterator<Future<BlurWorker.Result>> iter = taskList.get(tag).iterator(); while (iter.hasNext()) { if (iter.next().isDone()) { iter.remove(); } } if(taskList.get(tag).isEmpty()) { taskList.remove(tag); } } } public void executeOnFireAndForgetThreadPool(Runnable r) { fireAndForgetThreadPool.execute(r); } public void shutDown() { concurrentThreadPool.shutdown(); serialThreadPool.shutdown(); fireAndForgetThreadPool.shutdown(); } }