java-线程池(二)

继上一篇java-线程池(一)讲解了线程池的好处及常用线程池,这篇解析线程池源码。

线程池重点类如下

Executor
接口,仅execute方法,将任务放入线程池
ExecutorService
接口,继承Executor,增加对线程的状态获取
Executors
类,任务提交和线程池类别选择
ThreadPoolExecutor
类,线程池,负责对任务的调度和处理

(一)Executor

public interface Executor {  
        /**
         * 将线程放入线程池
         * @param command 要执行的异步任务
         */
        void execute(Runnable command);  
    } 

统一提供线程提交接口,所有线程池生成都必须继承。


(二)ExecutorService

public interface ExecutorService extends Executor {  
        void shutdown();  
        boolean isShutdown();  
        boolean isTerminated();  
        <T> Future<T> submit(Callable<T> task);
        <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
            throws InterruptedException;
        // 省略部分方法  
    }
在Executor的基础上,添加对线程的生命周期的控制(终止、唤醒等)


(三)Executors

将线程池的任务提交和执行分离,此部分是任务提交部分,提供四种基本的线程池。

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
        return new DelegatedScheduledExecutorService
            (new ScheduledThreadPoolExecutor(1));
    }

四种线程池对比


corePoolSize
maximumPoolSize
keepAliveTime
workQueue
newFixedThreadPool
nThreads
nThreads
0L
LinkedBlockingQueue
newSingleThreadExecutor
1 1 0L LinkedBlockingQueue
newCachedThreadPool
0 Integer.MAX_VALUE
60L SynchronousQueue
newScheduledThreadPool
corePoolSize
Integer.MAX_VALUE
0L
DelayedWorkQueue

corePoolSize:线程池维护线程的最小数量

maximumPoolSize:线程池维护的最大线程数量

keepAliveTime:线程销毁保留时间

workQueue:使用的任务保存队列


newFixedThreadPool定长线程,可固定最大线程数。

newSingleThreadExecutor提供单线程线程池,适合按顺序执行任务。

newCachedThreadPool提供了线程销毁缓冲期60L,最大线程数无上限,适合大量小任务执行。

newScheduledThreadPool可以延时和定期执行任务。

(四)ThreadPoolExecutor

/**
     * 核心方法,任务丢给线程池
     * @param command
     */
    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        // 如果线程数小于基本线程数,则创建线程并执行当前任务
        if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
            // 如线程数大于等于基本线程数或线程创建失败,则将当前任务放到工作队列中。
            if (runState == RUNNING && workQueue.offer(command)) {
                //若当前没任何线程执行,强制开始首个线程任务
                if (runState != RUNNING || poolSize == 0)
                    ensureQueuedTaskHandled(command);
            }

            // 如果线程池不处于运行中或任务无法放入队列,并且当前线程数量小于最大允许的线程数量,则创建一个线程执行任务。
            else if (!addIfUnderMaximumPoolSize(command))
                // 当任务无法成功接收时,按策略做异常处理
                reject(command); 
        }
    }

/**
     * 添加任务到线程池
     * @param firstTask
     * @return
     */
    private boolean addIfUnderCorePoolSize(Runnable firstTask) {
        Thread t = null;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            //线程数未满基本线程数且当前是运行状态时,开启新线程
            if (poolSize < corePoolSize && runState == RUNNING)
                t = addThread(firstTask);
        } finally {
            mainLock.unlock();
        }
        return t != null;
    }

/**
     * 给任务开启一个线程
     * 
     * @param firstTask
     * @return
     */
    private Thread addThread(Runnable firstTask) {
        //worker代表一个线程,有对整个线程的处理,当前任务执行完,自动拿队列任务执行
        Worker w = new Worker(firstTask);
        //工厂模式创建线程
        Thread t = threadFactory.newThread(w);
        boolean workerStarted = false;
        if (t != null) {
            if (t.isAlive()) // precheck that t is startable
                throw new IllegalThreadStateException();
            w.thread = t;
            workers.add(w);
            int nt = ++poolSize;
            //当前线程数已达最大数时,不再开启新线程
            if (nt > largestPoolSize)
                largestPoolSize = nt;
            try {
                t.start();
                workerStarted = true;
            }
            finally {
                if (!workerStarted)
                    workers.remove(w);
            }
        }
        return t;
    }




(五)线程池学习概要

线程池的合理运用,能提升系统性能,线程池创建有四种类型,各有利弊,具体情况具体分析。

后面会有专题讲解android性能优化,先准备下基本知识。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章