android.concurrent.ThreadPool.java Source code

Java tutorial

Introduction

Here is the source code for android.concurrent.ThreadPool.java

Source

/*
 * 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;
        }
    }
}