Java tutorial
/* * ThreadPoolManager.java * * Copyright 2011 androwa team, Inc. All rights reserved. * androwa PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package android.concurrent; import android.assist.Assert; import android.reflect.TrackingUtils; import android.support.v4.util.ArrayMap; import android.text.TextUtils; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** * ? * * @author ANDROWA TEAM * @version 1.0.0 * @since 1.0.0 Handy 2011-04-09 */ public class ThreadPool { public static final String M_POOL_NAME = "__DEFAULT_POOL"; /** * ? */ private static final int DEFAULT_BLOCKING_QUEUE_SIZE = 24; /** * */ private final static int CORE_POOL_SIZE = 12; /** * */ private final static int MAXIMUM_POOL_SIZE = 32; /** * */ private final static long KEEP_ALIVE_TIME = 500; /** * ?? */ private final static TimeUnit UNIT = TimeUnit.MILLISECONDS; /** * ? */ public static ThreadPool Impl = new ThreadPool(); /* *************************************** * * *************************************** */ /** * */ private ThreadPoolExecutor mDefaultThreadExecutor; /** * 64 */ private final ArrayMap<String, ExecutorService> mThreadPoolMap; /** * */ private ThreadPool() { // 16 mThreadPoolMap = new ArrayMap<String, ExecutorService>(16); mDefaultThreadExecutor = createThreadPoolExecutor(M_POOL_NAME); } /** * ? * * @return */ public ExecutorService obtain() { if (mDefaultThreadExecutor == null || mDefaultThreadExecutor.isShutdown()) { synchronized (ThreadPool.class) { if (mDefaultThreadExecutor == null || mDefaultThreadExecutor.isShutdown()) { mDefaultThreadExecutor = createThreadPoolExecutor(M_POOL_NAME); } } } return mDefaultThreadExecutor; } /** * ? * * @param poolName */ public synchronized ExecutorService create(String poolName) { Assert.notNull(poolName); ExecutorService excuter = createThreadPoolExecutor(poolName); put(poolName, excuter); return excuter; } /** * * * @param poolName * @param executor */ public synchronized void put(String poolName, ExecutorService executor) { if (!TextUtils.isEmpty(poolName) && executor != null) { if (mThreadPoolMap != null) { ExecutorService oldEcecutor = mThreadPoolMap.put(poolName, executor); if (oldEcecutor != null) { oldEcecutor.shutdown(); } } else { throw new RuntimeException("Prohibition of registration of ThreadPoolExecutors at run-time!"); } } else { throw new IllegalArgumentException("registed ThreadPoolExecutor is null."); } } /** * * * @param poolName */ public synchronized void remove(String poolName) { if (Assert.notEmpty(poolName) && Assert.containsKey(mThreadPoolMap, poolName)) { ExecutorService executor = mThreadPoolMap.remove(poolName); if (executor != null) { executor.shutdown(); } } } /** * ? * * @param poolName * @return */ public synchronized ExecutorService get(String poolName) { Assert.notNull(poolName); ExecutorService executor = null; if (Assert.containsKey(mThreadPoolMap, poolName)) { executor = mThreadPoolMap.get(poolName); } if (executor == null) { executor = create(poolName); } return executor; } /** * * * @param runnable */ public synchronized void execute(String poolName, Runnable runnable) { Assert.notNull(runnable); get(poolName).execute(TrackingUtils.proxy(runnable)); } /** * * * @param runnable */ public synchronized void execute(Runnable runnable) { Assert.notNull(runnable); obtain().execute(TrackingUtils.proxy(runnable)); } public void release() { if (mDefaultThreadExecutor != null) { mDefaultThreadExecutor.shutdownNow(); mDefaultThreadExecutor = null; } } /** * * * @param callable * @return */ public synchronized <V> Future<V> submit(Callable<V> callable) { Assert.notNull(callable); return obtain().submit(TrackingUtils.proxy(callable)); } private static ThreadPoolExecutor createThreadPoolExecutor(String poolName) { ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(DEFAULT_BLOCKING_QUEUE_SIZE); // CallerRunsPolicy policy = new CallerRunsPolicy(); ThreadPoolExecutor.DiscardPolicy policy = new ThreadPoolExecutor.DiscardPolicy(); ThreadPoolExecutor excuter = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, UNIT, queue, new PoolThreadFactory(poolName), policy); excuter.prestartAllCoreThreads(); excuter.allowCoreThreadTimeOut(true); return excuter; } /** * The default thread factory */ public static class PoolThreadFactory implements ThreadFactory { private static final AtomicInteger mPoolNumber = new AtomicInteger(1); private final ThreadGroup mThreadGroup; private final AtomicInteger mThreadNumber = new AtomicInteger(1); private final String mNamePrefix; public PoolThreadFactory(String poolName) { SecurityManager s = System.getSecurityManager(); mThreadGroup = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); mNamePrefix = String.format("%s_%d_", (Assert.notEmpty(poolName) ? poolName : M_POOL_NAME), mPoolNumber.getAndIncrement()); } public Thread newThread(Runnable r) { Thread t = new Thread(mThreadGroup, r, mNamePrefix + mThreadNumber.getAndIncrement(), 0); if (t.isDaemon()) { t.setDaemon(false); } if (t.getPriority() != Thread.NORM_PRIORITY) { t.setPriority(Thread.NORM_PRIORITY); } return t; } } }