线程池——张孝祥老师高新技术

来源:互联网 发布:公司域名申请 编辑:程序博客网 时间:2024/06/05 08:01
线程池——张孝祥老师高新技术


线程池的概念与Excutors类的应用
创建固定大小的线程池
创建缓存线程池
创建单一线程池


关闭线程池
shutdown与shutdownNow的比较


用线程池启动定时器
调用ScheduledExecutorService的schedule方法,返回的ScheduleFuture对象可以取消任务。
支持间隔重复任务的定时方式,不直接支持绝对定时方式,需要转换成相对时间方式。


ThreadPoolExecutor是jdk1.5之后并发库中提供的线程池工具类。通过该类可以构造一个指定大小的线程池,通过BlockingQueue阻塞队列来实现工作任务线程执行控制。通过传入不同的Queue实现类,实现不同的阻塞控制。还可以通过不同的线程构造,设置线程构造方法。为了发挥线程池性能,必须良好配置corePoolSize、maxPoolSize、queue、和线程池满的状态下的拒绝策略。
execute方法
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); // is shutdown or saturated
    }
}
当任务线程数目小于corePoolSize时,创建新线程执行当前任务,否则加入queue中缓存。当任务线程数超过corePoolSize,判断是否小于maxPoolSize,是则创建新线程运行,否则进行拒绝处理。
Worker对象用来执行具体任务
run方法如下
public void run() {
    try {
        Runnable task = firstTask;
        firstTask = null;
        //执行任务,并在执行完成后,通过getTask()获取下一个任务
        while (task != null || (task = getTask()) != null) {
            runTask(task);
            task = null;
        }
    } finally {
        workerDone(this);
    }
}
getTask()方法操作Queue缓冲队列获取新任务,如果当前任务线程数大于corePoolSize且无缓冲任务,则停止一个任务线程。如果任务线程数小于等于核心线程数但无缓冲任务,则阻塞当前任务线程。
Runnable getTask() {
    for (;;) {
        try {
            int state = runState;
            if (state > SHUTDOWN)
                return null;
            Runnable r;
            if (state == SHUTDOWN)  // Help drain queue
                r = workQueue.poll();
            //任务线程数超过核心池大小或允许一个超时时间等待新任务
            else if (poolSize > corePoolSize || allowCoreThreadTimeOut)
               //阻塞一个keepAliveTime时间
                r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS);
            else
                r = workQueue.take();  //阻塞当前线程
            if (r != null)
                return r;
            //任务缓冲池中没有任务,则允许停止一个任务线程,poolSize减少一个
            if (workerCanExit()) {
                if (runState >= SHUTDOWN) // Wake up others
                    interruptIdleWorkers();
                return null;
            }
            // Else retry
        } catch (InterruptedException ie) {
            // On interruption, re-check runState
        }
    }
}
在后续的workDone中及时调整了线程池的工作线程数目。
原创粉丝点击