博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java线程池之ThreadPoolExecutor
阅读量:6381 次
发布时间:2019-06-23

本文共 4935 字,大约阅读时间需要 16 分钟。

针对android中的多线程请求,本文主要介绍 android中线程池的基本使用。

1:线程池的分类

FixedThreadPool:它是一种线程数量固定的线程池,当线程处于空闲状态时,它们并不会被回收,除非线程池被关闭,当所有的线程都处于活动状态时,新任务都会处于等待状态,直到有线程空闲出来。该线程池中只有核心线程,并且这些核心线程不会被回收,这意味着它能够更加快速的响应外界的请求。

CachedThreadPool: 该线程池中线程数量不固定,并且内部只有非核心线程,其线程的最大值为 Integer.MAX_VALUE。所以可以认为该线程池中的线程数量可以任意大。该线程池的特定是当线程池中的线程都处于活动状态时,线程池会创建新的线程来处理新的任务,否则就会利用空闲的线程来处理新的任务。该线程池中的空闲线程都有超时机制,这个超时时长为 60s ,超过60s 空闲线程就会被回收。
ScheduledThreadPool: 该线程池中包含核心线程以及非核心线程,核心线程数量是固定的,而非核心线程数量是没有限制的,并且当非核心线程闲置时会被立即回收。
SingleThreadExecutor:该线程池是一个单例线程,其内部只有一个核心线程。

2:线程池的基本使用

FixedThreadPool:

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4)fixedThreadPool.execute(runnable)复制代码

CachedThreadPool:

ExecutorService cacheThreadPool = Executors.newCachedThreadPool() cacheThreadPool.execute(runnable)复制代码

ScheduledThreadPool:

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4) scheduledThreadPool.schedule(runnable3, 2000, TimeUnit.MILLISECONDS)复制代码

SingleThreadExecutor:

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor()singleThreadExecutor.execute(runnable)复制代码

2:线程池的基本使用

FixedThreadPool:

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4)fixedThreadPool.execute(runnable)复制代码

CachedThreadPool:

ExecutorService cacheThreadPool = Executors.newCachedThreadPool() cacheThreadPool.execute(runnable)复制代码

ScheduledThreadPool:

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4) scheduledThreadPool.schedule(runnable3, 2000, TimeUnit.MILLISECONDS)复制代码

SingleThreadExecutor:

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor()singleThreadExecutor.execute(runnable)复制代码

3: 线程池构造解析

android中线程池概念来源于java中的Executor,而Executor通过源码我们可以看出是一个接口;

public interface Executor {    void execute(Runnable command);}复制代码

内部只包含一个抽象方法 execute(….);

同时android中 重新定义了ExecutorService接口去继承上述接口;

public interface ExecutorService extends Executor{}复制代码

而 ExecutorService 接口的实现类是:

public abstract class AbstractExecutorService implements ExecutorService{}复制代码

抽象类AbstractExecutorService 的具体实现是:

public class ThreadPoolExecutor extends AbstractExecutorService{}复制代码

通过上述关系可以看到线程池的真正实现为ThreadPoolExecutor,在ThreadPoolExecutor 中提供了一系列的参数来创建不同的线程池。

下面我们来看ThreadPoolExecutor的构造函数:

public ThreadPoolExecutor(int corePoolSize,                              int maximumPoolSize,                              long keepAliveTime,                              TimeUnit unit,                              BlockingQueue workQueue,                              ThreadFactory threadFactory,                              RejectedExecutionHandler handler) {}复制代码

内部参数:

corePoolSize:线程的核心线程数;

maximumPoolSize:线程池所能容纳的最大线程数:
keepAliveTime:非核心线程闲置时的超时市场,超过这个时长非核心线程就会被回收
unit:用于指定keepAliveTime 的单位
workQueue:线程池中的任务队列
threadFactory:线程工厂,为线程池提供创建新线程的功能
handler:当线程池无法执行新的任务时,会调用handler的rejectedEcexutor方法来通知调用者。该参数不常用,可以忽略。
通过源码我们可以看到google是通过工厂方式去创建各种线程池,具体源码我们可以通过

public class Executors{}复制代码

该类可以看到内部通过各种方法去获取不同的线程池。

下面我们根据Executors 中各个方法去看各个线程池是如何实现的。

FixedThreadPool:

public static ExecutorService newFixedThreadPool(int nThreads) {        return new ThreadPoolExecutor(nThreads, nThreads,                                      0L, TimeUnit.MILLISECONDS,                                      new LinkedBlockingQueue());    }复制代码

FixedThreadPool 通过调用 ThreadPoolExecutor构造函数 可以看出实质上是通过外部设置了 核心线程数,以及非核心线程数。

CachedThreadPool:

public static ExecutorService newCachedThreadPool() {        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,                                      60L, TimeUnit.SECONDS,                                      new SynchronousQueue());    }复制代码

CachedThreadPool 内部可以看出实质上 核心线程数为0 ,而非核心线程数为Int最大值

SingleThreadExecutor:

public static ExecutorService newSingleThreadExecutor() {        return new FinalizableDelegatedExecutorService            (new ThreadPoolExecutor(1, 1,                                    0L, TimeUnit.MILLISECONDS,                                    new LinkedBlockingQueue()));    }复制代码

SingleThreadExecutor 可以看出实质上是核心线程数以及非核心线程数均为1;

ScheduledThreadPool:

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {        return new ScheduledThreadPoolExecutor(corePoolSize);    }public class ScheduledThreadPoolExecutor        extends ThreadPoolExecutor        implements ScheduledExecutorService {        ....         public ScheduledThreadPoolExecutor(int corePoolSize) {                super(corePoolSize, Integer.MAX_VALUE,                      DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,                      new DelayedWorkQueue());            }            ....    }复制代码

ScheduledThreadPool 可以看出核心线程数是通过外部设置,而非核心线程数实质是int的最大值。

4 : 线程池的基本执行流程

1:如果线程池中核心线程未达到上限那么,则会直接启动一个核心线程去执行任务;

2:如果核心线程达到上限,那么会将任务放到任务队列中,等待执行,
3:如果任务无法插入到任务队列中,则会开启一个非核心线程去执行任务,
4:如果线程池中的线程已经达到线程数量的上限,则将不会去执行任务,ThreadPoolExecutor将会调用RejectedExecutionHandler的rejectedExecution方法通知调用者。

以下通过图示来说明:

转载于:https://juejin.im/post/5c19ea81f265da6172656d7a

你可能感兴趣的文章
debug-stripped.ap_' specified for property 'resourceFile' does not exist
查看>>
利用MapReduce计算平均数
查看>>
scala-05-map映射
查看>>
Spring Boot - how to configure port
查看>>
右键添加复制路径选项
查看>>
DocFetcher 本机文件搜索工具
查看>>
ambassador 学习三 限速处理
查看>>
HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
查看>>
数据结构:最小生成树--Kruskal算法
查看>>
Swift_1_基本数据类型
查看>>
深入解析Vuex实战总结
查看>>
流水落花春去也
查看>>
【教训】为什么不作备份?!
查看>>
ThinkPHP3.0启动过程
查看>>
JAX-WS(JWS)发布WebService
查看>>
Centos7安装docker-compse踩过的坑
查看>>
细说Nullable<T>类型
查看>>
oracle 插入表数据的4种方式
查看>>
7.Ajax
查看>>
Linux vi/vim编辑器常用命令与用法总结
查看>>