Android线程池管理--示例

概述

本文章主要提供一款应用于Android App层的线程池管理类,主要解决以下问题:

1.解决传统单线程任务反复创建销毁造成的资源浪费

2.多线程频繁创建占用,容易出现资源竞争且缺乏统一管理,并且销毁频繁GC会导致系统卡顿,性能降低

示例

我们借助Java中ThreadPoolExecutor实现一个ThreadPoolProxy,核心方法主要为:

public synchronized void execute(Runnable run)

执行任务,当线程池处于关闭,将会重新创建新的线程池

public synchronized void cancel(Runnable run)

取消线程池中某个还未执行的任务

public synchronized boolean contains(Runnable run)

取消线程池中某个还未执行的任务

public synchronized void shutdown()

平缓关闭单任务线程池,但是会确保所有已经加入的任务都将会被执行完毕才关闭

public void stop()

立刻关闭线程池,并且正在执行的任务也将会被中断

管理类ThreadManager

区分提供两个独立的线程池,用于处理耗时及短耗时任务

public static ThreadPoolProxygetLongPool()

获取一个用于执行长耗时任务的线程池,避免和短耗时任务处在同一个队列而阻塞了重要的短耗时任务,通常用来联网操作

public static ThreadPoolProxygetShortPool()

获取一个用于执行短耗时任务的线程池,避免因为和耗时长的任务处在同一个队列而长时间得不到执行,通常用来执行本地的IO/SQL

源码

package com.car.test;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
import java.util.concurrent.TimeUnit;

/**
 * 一个简易的线程池管理类,提供三个线程池
 */
public class ThreadManager {
    // We want at least 2 threads and at most 4 threads in the core pool,
    // preferring to have 1 less than the CPU count to avoid saturating
    // the CPU with background work 核心池数量被限定在2到4之间。
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    public static final String DEFAULT_SINGLE_POOL_NAME = "DEFAULT_SINGLE_POOL_NAME";
    private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE_SECONDS = 30;

    private static ThreadPoolProxy mLongPool = null;
    private static final Object mLongLock = new Object();

    private static ThreadPoolProxy mShortPool = null;
    private static final Object mShortLock = new Object();

    private static ThreadPoolProxy mDownloadPool = null;
    private static Object mDownloadLock = new Object();

    private static Map mMap = new HashMap();
    private static final Object mSingleLock = new Object();

    /**
     * 获取下载线程
     */
    public static ThreadPoolProxy getDownloadPool() {
        synchronized (mDownloadLock) {
            if (mDownloadPool == null) {
                mDownloadPool = new ThreadPoolProxy();
            }
            return mDownloadPool;
        }
    }

    /**
     * 获取一个用于执行长耗时任务的线程池,避免和短耗时任务处在同一个队列而阻塞了重要的短耗时任务,通常用来联网操作
     */
    public static ThreadPoolProxy getLongPool() {
        synchronized (mLongLock) {
            if (mLongPool == null) {
                mLongPool = new ThreadPoolProxy();
            }
            return mLongPool;
        }
    }

    /**
     * 获取一个用于执行短耗时任务的线程池,避免因为和耗时长的任务处在同一个队列而长时间得不到执行,通常用来执行本地的IO/SQL
     */
    public static ThreadPoolProxy getShortPool() {
        synchronized (mShortLock) {
            if (mShortPool == null) {
                mShortPool = new ThreadPoolProxy();
            }
            return mShortPool;
        }
    }

    /**
     * 获取一个单线程池,所有任务将会被按照加入的顺序执行,免除了同步开销的问题
     */
    public static ThreadPoolProxy getSinglePool() {
        return getSinglePool(DEFAULT_SINGLE_POOL_NAME);
    }

    /**
     * 获取一个单线程池,所有任务将会被按照加入的顺序执行,免除了同步开销的问题
     */
    public static ThreadPoolProxy getSinglePool(String name) {
        synchronized (mSingleLock) {
            ThreadPoolProxy singlePool = mMap.get(name);
            if (singlePool == null) {
                singlePool = new ThreadPoolProxy();
                mMap.put(name, singlePool);
            }
            return singlePool;
        }
    }

    public static class ThreadPoolProxy {
        private ThreadPoolExecutor mPool;

        private ThreadPoolProxy() {
        }

        /**
         * 执行任务,当线程池处于关闭,将会重新创建新的线程池
         */
        public synchronized void execute(Runnable run) {
            if (run == null) {
                return;
            }
            if (mPool == null || mPool.isShutdown()) {
                //参数说明
                //当线程池中的线程小于mCorePoolSize,直接创建新的线程加入线程池执行任务
                //当线程池中的线程数目等于mCorePoolSize,将会把任务放入任务队列BlockingQueue中
                //当BlockingQueue中的任务放满了,将会创建新的线程去执行,
                //但是当总线程数大于mMaximumPoolSize时,将会抛出异常,交给RejectedExecutionHandler处理
                //mKeepAliveTime是线程执行完任务后,且队列中没有可以执行的任务,存活的时间,后面的参数是时间单位
                //ThreadFactory是每次创建新的线程工厂
                mPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, new LinkedBlockingQueue(), Executors.defaultThreadFactory(), new AbortPolicy());
            }
            mPool.execute(run);
        }

        /**
         * 取消线程池中某个还未执行的任务
         */
        public synchronized void cancel(Runnable run) {
            if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
                mPool.getQueue().remove(run);
            }
        }

        /**
         * 取消线程池中某个还未执行的任务
         */
        public synchronized boolean contains(Runnable run) {
            if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
                return mPool.getQueue().contains(run);
            } else {
                return false;
            }
        }

        /**
         * 立刻关闭线程池,并且正在执行的任务也将会被中断
         */
        public void stop() {
            if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
                mPool.shutdownNow();
            }
        }

        /**
         * 平缓关闭单任务线程池,但是会确保所有已经加入的任务都将会被执行完毕才关闭
         */
        public synchronized void shutdown() {
            if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
                mPool.shutdownNow();
            }
        }
    }
}


你可能感兴趣的:(Android线程池管理--示例)