线程池 一 ThreadPoolExecutor

java.util.concurrent
public class ThreadPoolExecutor extends AbstractExecutorService

ThreadPoolExecutor实现类

三种ThreadPoolExecutor实现类:

ExecutorService?newCachedThreadPool():
    无界线程池,如果有可用线程,当线程池调用execute, 将重用之前的构造函数。
    如果没有现有的线程可用,那么就创建新的线程并添加到池中。
    核心线程数为0,最大线程数为Integer最大值大小,超过0个的空闲线程在60秒后销毁

ExecutorService?newFixedThreadPool():
    有界线程池,可控制线程最大并发数,超出的线程会在队列中等待。
    核心线程数和最大线程数固定相等

ExecutorService?newSingleThreadExecutor():
    单线程线程池,核心线程数和最大线程数均为1
    每次只执行一个线程,多余的先存储到工作队列,一个一个执行,保证了线程的顺序执行。

三种线程池的构造函数:

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

四种ThreadPoolExecutor构造函数:

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue)

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory)

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler)

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

int corePoolSize:
    核心线程数,即使空闲也仍保留在池中的线程数

int maximumPoolSize:
    最大线程数(线程总数计算公式 = 核心线程数 + 非核心线程数)

BlockingQueue<Runnable> workQueue:
    阻塞队列,在执行任务之前用于保存任务的队列维护着等待执行的Runnable对象。
    当所有的核心线程都在干活时,新添加的任务会被添加到这个队列中等待处理,如果队列满了,则新建非核心线程执行任务

long keepAliveTime:
    保持激活时间,当线程数大于核心数时,这是多余的空闲线程在终止之前等待新任务的最大时间

TimeUnit unit:
    keepAliveTime的时间单位

threadFactory:
    线程工厂,主要用来创建线程
handler:
    表示当拒绝处理任务时的策略

执行过程

  1. 如果线程数量未达到corePoolSize,则新建一个线程(核心线程)执行任务
  2. 如果线程数量达到了corePools,则将任务移入队列等待
  3. 如果队列已满,新建线程(非核心线程)执行任务
  4. 如果队列已满,总线程数又达到了maximumPoolSize,就会由RejectedExecutionHandler抛出异常

拒绝策略(超过最大线程数时)

当线程池已经关闭或达到饱和(最大线程和队列都已满)状态时,新提交的任务将会被拒绝。

handler:表示当拒绝处理任务时的策略,有以下四种取值:

  1. AbortPolicy
    简单粗暴,直接抛出拒绝异常,这也是默认的拒绝策略。
  2. CallerRunsPolicy
    如果线程池未关闭,则会在调用者线程中直接执行新任务,这会导致主线程提交线程性能变慢。
  3. DiscardPolicy
    从方法看没做任务操作,即表示不处理新任务,即丢弃。
  4. DiscardOldestPolicy
    抛弃最老的任务,就是从队列取出最老的任务然后放入新的任务进行执行。

任务缓存队列及排队策略

workQueue,它用来存放等待执行的任务。

workQueue的类型为BlockingQueue<Runnable>,通常可以取下面三种类型:

  1. ArrayBlockingQueue:基于数组的先进先出队列,此队列创建时必须指定大小;
  2. LinkedBlockingQueue:基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE;
  3. synchronousQueue:这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务。

提交线程

ExecutorService接口继承了Executor接口,并声明了一些方法:submitinvokeAllinvokeAny以及shutDown

AbstractExecutorService实现了ExecutorService接口,基本实现了ExecutorService中声明的所有方法

ThreadPoolExecutor继承了类AbstractExecutorService

ThreadPoolExecutor类中有几个非常重要的方法:execute()submit()shutdown()shutdownNow()

ExecutorService es = Executors.newFixedThreadPool(3);

提交一个线程:

  1. es.submit(Runnble run);
  2. es.execute(Runnble run);

submit和execute分别有什么区别:

  1. execute没有返回值,如果不需要知道线程的结果就使用execute方法,性能会好很多。
  2. submit返回一个Future对象,如果想知道线程结果就使用submit提交,而且它能在主线程中通过Future的get方法捕获线程中的异常。

关闭线程池:

  1. es.shutdown();(不能够接受新的任务,它会等待所有任务执行完毕)
  2. es.shutdownNow();(不能接受新的任务,并且会去尝试终止正在执行的任务)此方法并不能保证一定会停止每个任务,可以通过Thread.interrupt来中断线程,如果中断失败,就可能无法终止线程池。

线程池容量的动态调整

ThreadPoolExecutor提供了动态调整线程池容量大小的方法:setCorePoolSize()setMaximumPoolSize()
setCorePoolSize:设置核心池大小
setMaximumPoolSize:设置线程池最大能创建的线程数目大小

线程池状态

ThreadPoolExecutor封装了两个概念字段:
workerCount:表示工作线程数,最大为(2^29)-1
runState:提供了对池生命周期的控制,包括以下几种状态:

  1. RUNNING:可以接收新的任务和队列任务
  2. SHUTDOWN:不接收新的任务,但是会运行队列任务
  3. STOP:不接收新任务,也不会运行队列任务,并且中断正在运行的任务
  4. TIDYING:所有任务都已经终止,workerCount为0,当池状态为TIDYING时将会运行terminated()方法
  5. TERMINATED:terminated函数完成执行。

转换:

原文地址:https://www.cnblogs.com/loveer/p/11414605.html

时间: 2024-10-09 04:46:50

线程池 一 ThreadPoolExecutor的相关文章

线程池.(Executors,ThreadPoolExecutor,BlockingQueue,RejectedExecutionHandler).介绍

线程池 Android里面,耗时的网络操作,都会开子线程,在程序里面直接开过多的线程会消耗过多的资源,在众多的开源框架中也总能看到线程池的踪影,所以线程池是必须要会把握的一个知识点; 线程运行机制 开启线程过多,会消耗cpu资源 单核cpu,同一时刻只能处理一个线程,多核cpu同一时刻可以处理多个线程 操作系统为每个运行线程安排一定的CPU时间----时间片,系统通过一种循环的方式为线程提供时间片,线程在自己的时间内运行,因为时间相当短,多个线程频繁地发生切换,因此给用户的感觉就是好像多个线程同

Java并发编程:Java线程池核心ThreadPoolExecutor的使用和原理分析

目录 引出线程池 Executor框架 ThreadPoolExecutor详解 构造函数 重要的变量 线程池执行流程 任务队列workQueue 任务拒绝策略 线程池的关闭 ThreadPoolExecutor创建线程池实例 参考: 引出线程池 线程是并发编程的基础,前面的文章里,我们的实例基本都是基于线程开发作为实例,并且都是使用的时候就创建一个线程.这种方式比较简单,但是存在一个问题,那就是线程的数量问题. 假设有一个系统比较复杂,需要的线程数很多,如果都是采用这种方式来创建线程的话,那么

线程池之 ThreadPoolExecutor

线程池之 ThreadPoolExecutor + 面试题 线程池介绍 线程池(Thread Pool):把一个或多个线程通过统一的方式进行调度和重复使用的技术,避免了因为线程过多而带来使用上的开销. 为什么要使用线程池? 可重复使用已有线程,避免对象创建.消亡和过度切换的性能开销. 避免创建大量同类线程所导致的资源过度竞争和内存溢出的问题. 支持更多功能,比如延迟任务线程池(newScheduledThreadPool)和缓存线程池(newCachedThreadPool)等. 线程池使用 创

高并发之——不得不说的线程池与ThreadPoolExecutor类浅析

一.抛砖引玉 既然Java中支持以多线程的方式来执行相应的任务,但为什么在JDK1.5中又提供了线程池技术呢?这个问题大家自行脑补,多动脑,肯定没坏处,哈哈哈... 说起Java中的线程池技术,在很多框架和异步处理中间件中都有涉及,而且性能经受起了长久的考验.可以这样说,Java的线程池技术是Java最核心的技术之一,在Java的高并发领域中,Java的线程池技术是一个永远绕不开的话题.既然Java的线程池技术这么重要(怎么能说是这么重要呢?那是相当的重要,那家伙老重要了,哈哈哈),那么,本文我

线程池:ThreadPoolExecutor

[ThreadPoolExecutor的使用和思考] public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)     1. 参数解释corePoolSize:

Android线程池(二)——ThreadPoolExecutor及其拒绝策略RejectedExecutionHandler使用演示样例

MainActivity例如以下: package cc.vv; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import android.os.Bundle; import android.app.Activity; /** * Demo描写叙述: * 线程池(Threa

线程池之ThreadPoolExecutor

所属包: java.util.concurrent.ThreadPoolExecutor 类关系: public class ThreadPoolExecutor extends AbstractExecutorService 1. 继承关系 ThreadPoolExecutor 继承了一个抽象类:AbstractExecutorService public abstract class AbstractExecutorService implements ExecutorService 而这个

Java线程池之ThreadPoolExecutor

前言 线程池可以提高程序的并发性能(当然是合适的情况下),因为对于没有线程的情况下,我们每一次提交任务都新建一个线程,这种方法存在不少缺陷: 1.  线程的创建和销毁的开销非常高,线程的创建需要时间,会延迟任务的执行,会消耗大量的系统资源. 2.  活跃的线程会消耗系统资源,而大量的空闲线程会占用许多内存,给垃圾回收器带来很大的压力,而大量线程在竞争CPU资源的时间还会产生气体的性能开销. 3.  系统在可创建的线程上存在一个限制,如果超过了这个限制,很可能抛出OOM. 我们不难发现,在一定范围

Android线程池(二)——ThreadPoolExecutor及其拒绝策略RejectedExecutionHandler使用示例

MainActivity如下: package cc.vv; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import android.os.Bundle; import android.app.Activity; /** * Demo描述: * 线程池(ThreadPoo