线程池分析

来源:互联网 发布:宠物翻译器软件 编辑:程序博客网 时间:2024/06/10 00:19

1,线程池

当进程中线程较少时,可以手动去新建thread。但是如果大量的线程会使进程管理很混乱,并且不断的创建销毁线程影响性能。在此情况下,线程池诞生了。线程池优点如下,

减少创建和销毁线程的次数,每个工作线程可以多次使用

可根据系统情况调整执行的线程数量,防止消耗过多内存。

2 ThreadPoolExecutor

2.1 构造方法

AsyncTask构造ThreadPoolExecutor如下,

public static final Executor THREAD_POOL_EXECUTOR            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,                    TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

1,第一个参数为int,线程池的核心线程数,核心线程会一直存活。

2,第二个参数为int,线程池最大的线程数量,超过的新线程就会被阻塞。

3,第三个参数为int,第四个参数为时间单位,单位有TimeUnit.MILLISECONDS(ms)/

TimeUnit.SECONDS(s)/TimeUnit.MINITES(分)等。表示非核心线程闲置时间超过这个时长就会被回收。

4,第五个参数表示线程池中的任务队列, AsyncTask中值为128

5,第六个参数是线程工厂,只是为线程池创建新的线程。

AsyncTask中这6个参数如下,

private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); // 一般为8    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;    private static final int KEEP_ALIVE = 1;    private static final ThreadFactory sThreadFactory = new ThreadFactory() {        private final AtomicInteger mCount = new AtomicInteger(1);        public Thread newThread(Runnable r) {            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());        }    };  // ThreadFactory是一个仅有newThread方法的接口    private static final BlockingQueue<Runnable> sPoolWorkQueue =            new LinkedBlockingQueue<Runnable>(128);

2.1 ThreadPoolExecutor分类

Executors类中封装了几个常用的线程池,也是通过new ThreadPoolExecutor来实现的。

2.1.1 newFixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads) {        return new ThreadPoolExecutor(nThreads, nThreads,                                      0L, TimeUnit.MILLISECONDS,                                      new LinkedBlockingQueue<Runnable>());    }

newFixedThreadPool特点:

1,所有线程都是核心线程,都处于活动状态,在线程池被关闭时才回收。

2,无超时机制,任务队列无大小限制。

优点:更快响应外界的请求。

2.1.2 newSingleThreadExecutor

public static ExecutorService newSingleThreadExecutor() {        return new FinalizableDelegatedExecutorService            (new ThreadPoolExecutor(1, 1,                                    0L, TimeUnit.MILLISECONDS,                                    new LinkedBlockingQueue<Runnable>()));    }

newSingleThreadExecutor特点:

1,仅有一个核心线程。

2,无超时机制,任务队列无大小限制。

优点:所有任务都在一个线程中按照顺序执行,所以不需要处理线程同步问题。

2.1.3 newCachedThreadPool

public static ExecutorService newCachedThreadPool() {        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,                                      60L, TimeUnit.SECONDS,                                      new SynchronousQueue<Runnable>());    }

newCachedThreadPool特点:

1,无核心线程,都是非核心线程。

2,超过60s的空闲线程就会被回收。

优点:适合执行大量耗时较少的任务。

2.1.4 newScheduledThreadPool

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {        return new ScheduledThreadPoolExecutor(corePoolSize);    }public ScheduledThreadPoolExecutor(int corePoolSize,                                       ThreadFactory threadFactory,                                       RejectedExecutionHandler handler) {        super(corePoolSize, Integer.MAX_VALUE,              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,              new DelayedWorkQueue(), threadFactory, handler);}

ScheduledThreadPoolExecutor继承于ThreadPoolExecutor

ScheduledThreadPoolExecutor特点:

1,非核心线程数无限制。

优点:适合执行定时任务和具有固定周期的重复任务。

当然还有一些其他的线程池未说明,例如ForkJoinPool

3 execute

Execute的总体调用流程图如下,


Execute方法如下,

public void execute(Runnable command) {        if (command == null)            throw new NullPointerException();        int c = ctl.get();        if (workerCountOf(c) < corePoolSize) {            if (addWorker(command, true))                return;            c = ctl.get();        }        if (isRunning(c) && workQueue.offer(command)) {            int recheck = ctl.get();            if (! isRunning(recheck) && remove(command))                reject(command);            else if (workerCountOf(recheck) == 0)                addWorker(null, false);        }        else if (!addWorker(command, false))            reject(command);    }

ctl是ThreadPoolExecutor的一个重要属性,它记录着ThreadPoolExecutor的线程数量和线程状态。有32位,其中前三位用于记录线程状态,后29位用于记录线程的数量。那线程状态一共有5种状态。

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));    private static final int COUNT_BITS = Integer.SIZE - 3;    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;    // runState is stored in the high-order bits    private static final int RUNNING    = -1 << COUNT_BITS;    private static final int SHUTDOWN   =  0 << COUNT_BITS;    private static final int STOP       =  1 << COUNT_BITS;    private static final int TIDYING    =  2 << COUNT_BITS;    private static final int TERMINATED =  3 << COUNT_BITS;

addWorker方法如下,

private boolean addWorker(Runnable firstTask, boolean core) { // core表示是否是核心线程        retry:        for (;;) {            int c = ctl.get();            int rs = runStateOf(c);            // Check if queue empty only if necessary.            if (rs >= SHUTDOWN &&                ! (rs == SHUTDOWN &&                   firstTask == null &&                   ! workQueue.isEmpty()))                return false;            for (;;) {                int wc = workerCountOf(c);                if (wc >= CAPACITY ||                    wc >= (core ? corePoolSize : maximumPoolSize))                    return false;                if (compareAndIncrementWorkerCount(c))                    break retry;                c = ctl.get();  // Re-read ctl                if (runStateOf(c) != rs)                    continue retry;                // else CAS failed due to workerCount change; retry inner loop            }        }        boolean workerStarted = false;        boolean workerAdded = false;        Worker w = null;        try {            w = new Worker(firstTask);            final Thread t = w.thread;            if (t != null) {                final ReentrantLock mainLock = this.mainLock;                mainLock.lock();                try {                    // Recheck while holding lock.                    // Back out on ThreadFactory failure or if                    // shut down before lock acquired.                    int rs = runStateOf(ctl.get());                    if (rs < SHUTDOWN ||                        (rs == SHUTDOWN && firstTask == null)) {                        if (t.isAlive()) // precheck that t is startable                            throw new IllegalThreadStateException();                        workers.add(w);                        int s = workers.size();                        if (s > largestPoolSize)                            largestPoolSize = s;                        workerAdded = true;                    }                } finally {                    mainLock.unlock();                }                if (workerAdded) {                    t.start();                    workerStarted = true;                }            }        } finally {            if (! workerStarted)                addWorkerFailed(w);        }        return workerStarted;    }

首先新建一个线程对象,然后将该对象放入workers的HashSet中,最后开始运行该线程。

private final HashSet<Worker> workers = new HashSet<Worker>();

runWorker方法如下,

final void runWorker(Worker w) {        Thread wt = Thread.currentThread();        Runnable task = w.firstTask;        w.firstTask = null;        w.unlock(); // allow interrupts        boolean completedAbruptly = true;        try {            while (task != null || (task = getTask()) != null) {                w.lock();                // If pool is stopping, ensure thread is interrupted;                // if not, ensure thread is not interrupted.  This                // requires a recheck in second case to deal with                // shutdownNow race while clearing interrupt                if ((runStateAtLeast(ctl.get(), STOP) ||                     (Thread.interrupted() &&                      runStateAtLeast(ctl.get(), STOP))) &&                    !wt.isInterrupted())                    wt.interrupt();                try {                    beforeExecute(wt, task);                    Throwable thrown = null;                    try {                        task.run();                    } catch (RuntimeException x) {                        thrown = x; throw x;                    } catch (Error x) {                        thrown = x; throw x;                    } catch (Throwable x) {                        thrown = x; throw new Error(x);                    } finally {                        afterExecute(task, thrown);                    }                } finally {                    task = null;                    w.completedTasks++;                    w.unlock();                }            }            completedAbruptly = false;        } finally {            processWorkerExit(w, completedAbruptly);        }    }

按照顺序调用如下三个方法,

beforeExecute

task.run()

afterExecute

其中, task是回调对象,是AsyncTask中的FutureTask对象。

0 0
原创粉丝点击