在应用程序中,总是会出现大量的任务,包括相同类型的和不同类型的。要快速处理这些任务,常见方法就是利用多线程,但是也不可能为每个任务都创建一个线程,这样内存也不够,并且线程的创建销毁开销很大。最好是少量线程处理大量任务,实现线程的复用,Executor干的就是这事。程序只需要把任务提交给Executor,由Executor来确定怎么来执行这个任务,即执行策略。Executor的关闭很重要,如果Executor如果没有关闭,那JVM将无法结束。关闭方法有shutdown,shutdownNow,shutdown方法执行平缓关闭,若该任务没有提交则拒绝提交,若该任务已经提交但是没有执行,将等待它执行完成,若该任务已经执行将等待它执行完成。shutdownNow是粗暴关闭,取消现在执行的任务,拒绝处理新任务,不再启动线程池队列中已提交的任务。当所有已经提交到Executor的任务都执行完成时,Executor将进入terminatede终止状态。

线程池的底层原理:数据结构:线程池管理器(ThreadpoolFactory),worker,任务队列Blockqueue;线程池的调度:新提交一个任务时,所有看下现有的线程数量是不是达到了corepoolSize,如果没有将新建一个线程thread,该线程将执行该任务,当该任务执行完成时,它会去任务队列中取出任务然后执行任务。若当前线程的数量大于corepoolSize小于maxpoolSize,则看下任务队列是否已经满了,若满了则新建线程thread,若没有满则将任务丢到任务队列中。

任务的取消和关闭

建设一个任务执行到一半,程序想取消这个任务,那怎么办呢?最好的方法是由每个任务自己来决定如何取消自己,这将保持数据的一致性,不会乱。常见的方法是轮询一个取消标志位,当该标志位被设立了,则执行自己的取消策略。这种方式会有个弊端,当执行该任务的线程由于某种原因被阻塞掉,那它将看不到标志位的设立,这个时候将加入中断Interrupted。当调用Thread.interrupted()时,线程的中断标志位会被设立,阻塞方法会检查中断标志位,将发现中断标志位为true时,将结束阻塞,重置中断位,提前返回并抛出中断异常。中断处理策略:抛出异常(我不想管了,谁爱管谁管),捕获异常(管了就不能无作为),恢复中断位(我想管,我告诉别人我是要中断的)。说了这么多如何管理任务的生命周期,最后发现Future已经提供了任务的周期的管理抽象,尴尬。对于不可中断的阻塞方法(同步io,Selector.select()方法,获取内置锁)通过中断不能达到取消任务的效果,只能特殊处理,比如说关闭socket.close(),抛出中断异常。当一个线程执行任务时,任务抛出一个未受检异常。jvm将捕获到异常,并终止线程,但是对于Executor这样的服务来说,终止一个线程可能会使它产生影响,所以它捕获异常并新增一条工作者线程(具体是新增还是不管看当前的线程数)。虽然这看起来好像没什么问题,但是这对于程序来说却显的莫名其妙,一个任务无声无息就取消了。针对这种情况提供了一个UncaughtExceptionHandler异常捕获器,线程池可以为每个线程配一个异常捕获器(通过线程池管理器实现)。

Executor以及线程池的更多相关文章

  1. 多线程-Executors和Executor,线程池

    jdk1.5之前,所有的线程都是需要自己手动创建的,由jvm销毁,当请求过多的时候,频繁的创建和销毁线程是非常浪费资源的.jdk1.5为此做了优化,提供了 java.util.concurrent 包 ...

  2. 戏(细)说Executor框架线程池任务执行全过程(上)

    一.前言 1.5后引入的Executor框架的最大优点是把任务的提交和执行解耦.要执行任务的人只需把Task描述清楚,然后提交即可.这个Task是怎么被执行的,被谁执行的,什么时候执行的,提交的人就不 ...

  3. 戏(细)说Executor框架线程池任务执行全过程(下)

    上一篇文章中通过引入的一个例子介绍了在Executor框架下,提交一个任务的过程,这个过程就像我们老大的老大要找个老大来执行一个任务那样简单.并通过剖析ExecutorService的一种经典实现Th ...

  4. Java 并发 —— Thread、Executor、线程池

    Java 线程池: ThreadPoolExecutor,创建此线程池的方法: new Executors.newCachedThreadPool():尽量避免使用,其无法控制线程数量, Schedu ...

  5. 启用Executor初始化线程池

    前言 上文我们介绍了JDK中的线程池框架Executor.我们知道,只要需要创建线程的情况下,即使是在单线程模式下,我们也要尽量使用Executor.即: ExecutorService fixedT ...

  6. Java并发编程的艺术(十一)——Executor与线程池

    Executor框架简介 从JDK5开始,把工作单元和执行机制分离开来了,工作的单元包括Runnable和Callable,执行机制就是由Executor框架提供. Executor两级调度模型 Ho ...

  7. JAVA Executor(线程池)框架

    一.Executor概述 为更好控制线程,jdk提供一套线程管理框架Executor,帮助开发人员有效地进行线程控制.它们都位于java.util.concurrent包中,是jdk并发包的核心.其中 ...

  8. Java 并发编程中的 Executor 框架与线程池

    Java 5 开始引入 Conccurent 软件包,提供完备的并发能力,对线程池有了更好的支持.其中,Executor 框架是最值得称道的. Executor框架是指java 5中引入的一系列并发库 ...

  9. 2,Executor线程池

    一,Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.co ...

随机推荐

  1. 一个不错的windows编程网址

    http://www.zklmc.com/ 含有MFC,C#,web开发资料

  2. ios常用资源网址链接

    M了个J博客 http://www.cnblogs.com/mjios/tag/objective-c/  Cocoa China http://www.cocoachina.com  git网 ht ...

  3. windows 2003装.net 4.0时提示 WIC windows Imaging Component

    运行此安装程序之前,必须安装32位windows映像处理组件(WIC) WIC windows Imaging Component下载地址: http://download.microsoft.com ...

  4. 每天一个Linux命令(06)--rmdir命令

    终于忙完了公司的事,可以安静的充充电了. 今天学习一下Linux中命令:rmdir 命令,rmdir是常用的命令,该命令的功能是删除空目录,一个目录被删除之前必须是空的.(注意,rm -r dir 命 ...

  5. python性能优化

      注意:本文除非特殊指明,”python“都是代表CPython,即C语言实现的标准python,且本文所讨论的是版本为2.7的CPython. python为什么性能差: 当我们提到一门编程语言的 ...

  6. 自定义分页Gridview中Excel导出

    先上图,如图所示导出所有查询出的数据 用的是AspNetPager分页控件,这个导出方法,不受分页和gridview列中数据的约束,可以导出您想导出的数据 首先前台页面代码,lblink即为导出exc ...

  7. Python 引用、浅拷贝、深拷贝解析

    引用 Python是动态数据类型的语言,故在对变量进行赋值时是不用制定变量类型的. 或者说,你可以把变量赋值的过程,当作是贴一个标签,去引用该数据. 看下面的例子: In [54]: a=4 In [ ...

  8. .NET 三层架构

    三层架构简介: 三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer).业务逻辑层(Business Lo ...

  9. 1593: [Usaco2008 Feb]Hotel 旅馆

    1593: [Usaco2008 Feb]Hotel 旅馆 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 391  Solved: 228[Submit ...

  10. hdoj 1175 (bfs)

    题意: 判断两点之间是否可以通过至多有两次转变方向以达到相连,就是平时玩的连连看游戏,但是不能从外面绕过去. 思路:bfs,给每个加入的队列的点添加转变方向次数turn和点当前要走的方向dir属性,起 ...