jdk1.5引入Executor线程池框架,通过它把任务的提交和执行进行解耦,只需要定义好任务,然后提交给线程池,而不用关心该任务是如何执行、被哪个线程执行,以及什么时候执行。

初始化线程池(4种)

简介:

Java线程池的工厂类:Executors类,

初始化4种类型的线程池:

newFixedThreadPool()
说明:初始化一个指定线程数的线程池,其中corePoolSize == maxiPoolSize,使用LinkedBlockingQuene作为阻塞队列
特点:即使当线程池没有可执行任务时,也不会释放线程。
newCachedThreadPool()
说明:初始化一个可以缓存线程的线程池,默认缓存60s,线程池的线程数可达到Integer.MAX_VALUE,即2147483647,内部使用SynchronousQueue作为阻塞队列;
特点:在没有任务执行时,当线程的空闲时间超过keepAliveTime,会自动释放线程资源;当提交新任务时,如果没有空闲线程,则创建新线程执行任务,会导致一定的系统开销;
因此,使用时要注意控制并发的任务数,防止因创建大量的线程导致而降低性能。
newSingleThreadExecutor()
说明:初始化只有一个线程的线程池,内部使用LinkedBlockingQueue作为阻塞队列。
特点:如果该线程异常结束,会重新创建一个新的线程继续执行任务,唯一的线程可以保证所提交任务的顺序执行
newScheduledThreadPool()
特定:初始化的线程池可以在指定的时间内周期性的执行所提交的任务,在实际的业务场景中可以使用该线程池定期的同步数据。

总结:除了newScheduledThreadPool的内部实现特殊一点之外,其它线程池内部都是基于ThreadPoolExecutor类(Executor的子类)实现的。

ThreadPoolExecutor内部具体实现:

ThreadPoolExecutor类构造器语法形式:

ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,timeUnit,workQueue,threadFactory,handle);

方法参数:
   corePoolSize:核心线程数

   maxPoolSize:最大线程数

     keepAliveTime:线程存活时间(在corePore<*<maxPoolSize情况下有用)
     timeUnit:存活时间的时间单位
     workQueue:阻塞队列(用来保存等待被执行的任务)

注:关于workQueue参数的取值,JDK提供了4种阻塞队列类型供选择:
        ArrayBlockingQueue:基于数组结构的有界阻塞队列,按FIFO排序任务;

        inkedBlockingQuene:基于链表结构的阻塞队列,按FIFO排序任务,吞吐量通常要高于  

            SynchronousQuene:一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于ArrayBlockingQuene;


        PriorityBlockingQuene:具有优先级的无界阻塞队列

 threadFactory:线程工厂,主要用来创建线程;

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

 注: 当线程池的饱和策略,当阻塞队列满了,且没有空闲的工作线程,如果继续提交任务,必须采取一种策略处理该任务,线程池提供了4种策略:

    ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

    ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。

    ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)

    ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

    当然也可以根据应用场景实现RejectedExecutionHandler接口,自定义饱和策略,如记录日志或持久化存储不能处理的任务。


 线程池的状态(5种)

其中AtomicInteger变量ctl的功能非常强大:利用低29位表示线程池中线程数,通过高3位表示线程池的运行状态:
1、RUNNING:-1 <<
COUNT_BITS,即高3位为111,该状态的线程池会接收新任务,并处理阻塞队列中的任务;
2、SHUTDOWN: 0
<< COUNT_BITS,即高3位为000,该状态的线程池不会接收新任务,但会处理阻塞队列中的任务;
3、STOP : 1 << COUNT_BITS,即高3位为001,该状态的线程不会接收新任务,也不会处理阻塞队列中的任务,而且会中断正在运行的任务;
4、TIDYING : 2 << COUNT_BITS,即高3位为010,该状态表示线程池对线程进行整理优化;
5、TERMINATED: 3
<< COUNT_BITS,即高3位为011,该状态表示线程池停止工作;


 向线程池提交任务(2种)

有两种方式:


Executor.execute(Runnable command);

     
ExecutorService.submit(Callable<T> task);

execute()内部实现

1.首次通过workCountof()获知当前线程池中的线程数,

如果小于corePoolSize, 就通过addWorker()创建线程并执行该任务;

 否则,将该任务放入阻塞队列;

2. 如果能成功将任务放入阻塞队列中,

如果当前线程池是非RUNNING状态,则将该任务从阻塞队列中移除,然后执行reject()处理该任务;

如果当前线程池处于RUNNING状态,则需要再次检查线程池(因为可能在上次检查后,有线程资源被释放),是否有空闲的线程;如果有则执行该任务;

3、如果不能将任务放入阻塞队列中,说明阻塞队列已满;那么将通过addWoker()尝试创建一个新的线程去执行这个任务;如果addWoker()执行失败,说明线程池中线程数达到maxPoolSize,则执行reject()处理任务;

 sumbit()内部实现

会将提交的Callable任务会被封装成了一个FutureTask对象

FutureTask类实现了Runnable接口,这样就可以通过Executor.execute()提交FutureTask到线程池中等待被执行,最终执行的是FutureTask的run方法;

比较:

两个方法都可以向线程池提交任务,execute()方法的返回类型是void,它定义在Executor接口中, 而submit()方法可以返回持有计算结果的Future对象,它定义在ExecutorService接口中,它扩展了Executor接口,其它线程池类像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有这些方法。


线程池的关闭(2种)

  ThreadPoolExecutor提供了两个方法,用于线程池的关闭,分别是shutdown()和shutdownNow(),其中:

    shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务

    shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务


线程池容量的动态调整

  ThreadPoolExecutor提供了动态调整线程池容量大小的方法:setCorePoolSize()和setMaximumPoolSize(),

总结:

线程池中的核心线程数,当提交一个任务时,线程池创建一个新线程执行任务,直到当前线程数等于corePoolSize;如果当前线程数为corePoolSize,继续提交的任务被保存到阻塞队列中,等待被执行;如果阻塞队列满了,那就创建新的线程执行当前任务;直到线程池中的线程数达到maxPoolSize,这时再有任务来,只能执行reject()处理该任务;

注:如果执行了线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有核心线程。

 

参考&&推荐:http://www.jianshu.com/p/87bff5cc8d8c

Java中线程池的实现原理-求职必备的更多相关文章

  1. Java中线程池的实现原理

    知识点总结 ---------------------------------------------------------------------------------------------- ...

  2. Java中线程池,你真的会用吗?

    在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建 ...

  3. 沉淀再出发:java中线程池解析

    沉淀再出发:java中线程池解析 一.前言 在多线程执行的环境之中,如果线程执行的时间短但是启动的线程又非常多,线程运转的时间基本上浪费在了创建和销毁上面,因此有没有一种方式能够让一个线程执行完自己的 ...

  4. Java中线程池,你真的会用吗?ExecutorService ThreadPoolExcutor

    原文:https://www.hollischuang.com/archives/2888 在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及 ...

  5. java中线程池的几种实现方式

    1.线程池简介:    多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.        假设一个服务器完成一项任务所需时间为:T1 创建 ...

  6. 第九章 Java中线程池

    Java中的线程池是运用场景最多的并发框架,几乎所有需求异步或并发执行任务的程序都可以使用线程池.在开发过程中,合理地使用线程池能够带来3个好处. 降低资源消耗:通过重复利用已创建的线程降低线程创建和 ...

  7. java中线程池创建的几种方式

    java中创建线程池的方式一般有两种: 通过Executors工厂方法创建 通过new ThreadPoolExecutor(int corePoolSize, int maximumPoolSize ...

  8. Java中线程池的学习

    线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程 ...

  9. 线程池;java的线程池的实现原理;适用于频繁互动(如电商网站)

    线程池是一种多线程处理形式,处理过程中将任务加入到队列,然后在创建线程后自己主动启动这些任务.线程池线程都是后台线程.每一个线程都使用默认的堆栈大小,以默认的优先级执行.并处于多线程单元中. 假设某个 ...

随机推荐

  1. A2dp连接流程源码分析

    在上一篇文章中,我们已经分析了:a2dp初始化流程 这篇文章主要分析a2dp的连接流程,其中还是涉及到一些底层的profile以及protocol,SDP.AVDTP以及L2CAP等. 当蓝牙设备与主 ...

  2. R绘图 第十二篇:散点图(高级)

    散点图用于描述两个连续性变量间的关系,三个变量之间的关系可以通过3D图形或气泡来展示,多个变量之间的两两关系可以通过散点图矩阵来展示. 一,添加了最佳拟合曲线的散点图 使用基础函数plot(x,y)来 ...

  3. 使用IdentityServer4实现一个简单的Oauth2客户端模式授权

    1.首先新建一个webAPI项目做为IdentityServer的服务端,提供生成Token的服务,首先修改Startup.cs文件,如下图: 2.增加一个Config.cs文件,以便于提供资源和认证 ...

  4. ansible环境部署及常用模块总结 - 运维笔记

    一.  Ansible 介绍Ansible是一个配置管理系统configuration management system, python 语言是运维人员必须会的语言, ansible 是一个基于py ...

  5. Mysql双主热备+LVS+Keepalived高可用操作记录

    MySQL复制能够保证数据的冗余的同时可以做读写分离来分担系统压力,如果是主主复制还可以很好的避免主节点的单点故障.然而MySQL主主复制存在一些问题无法满足我们的实际需要:未提供统一访问入口来实现负 ...

  6. M2事后会议报告

    设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? Beta阶段的爬虫需要更稳定.更高效.操作更便捷.在定义中爬取对性能和功能的要求高,典型用户和场景 ...

  7. 2-Twenty third Scrum Meeting-20151229

    前言 因为服务器关闭至今,我们的开发项目也遭遇停滞一个星期.与网站开发负责人员协商之后,今天继续开放服务器.我们的项目也能够继续下去.比规定的开发时间(截止为2015/12/29)推迟,因此我们今天又 ...

  8. 【Beta阶段】M2事后分析

    先上照片,最后一次开会了啊... 计划 你原计划的工作是否最后都做完了? 如果有没做完的,为什么? 答:没有全部做完,到目前为止,我们的还有几个实验的报告生成功能没有上线.这几个实验的数据处理文件已经 ...

  9. pandas修改全列的时间格式 无需使用apply

    df.date.dt.strftime('%Y%m%d') #实现全列修改时间格式

  10. the confilict between validation and readonly in jquery

    How can I disable jquery validation on readonly fields? http://stackoverflow.com/questions/10803294/ ...