`

JDK 中的线程

 
阅读更多

concurrent并发包里面几个重要的接口有:Executor、ExecutorService, ScheduledExecutorService
重要的实现类有:ScheduledThreadPoolExecutor, ThreadPoolExecutor
关于这几个接口和实现类的类图可以参见文档最后的UML图,图中对一些比较重要的属性、方法进行红色标识,可以重点关注;

先来说说java.util.concurrent.ThreadPoolExecutor ,也就是我们经常说到的线程池,通过该类,应用可以直接拿来使用,只要在初始化时设置不同的参数即可;其主要的参数有以下几个:

  • corePoolSize : 线程池维护线程的最少数量
  • maximumPoolSize :线程池维护线程的最大数量
  • keepAliveTime : 线程池维护线程所允许的空闲时间
  • unit : 线程池维护线程所允许的空闲时间的单位
  • workQueue : 线程池所使用的缓冲队列
  • handler : 线程池对拒绝任务的处理策略

一个任务通过execute(Runnable)方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是Runnable类型对象的run()方法;注意:是Runnable,而不是Thread

当一个任务通过execute(Runnable)方法欲添加到线程池时:

  • 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
  • 如果此时线程池中的数量等于corePoolSize,但是缓冲队列workQueue未满,那么任务被放入缓冲队列。
  • 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
  • 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过handler所指定的策略来处理此任务。
  • 从上面可以看出线程池中处理任务的优先级为:
    核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。

当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。

unit可选的参数为java.util.concurrent.TimeUnit中的几个静态属性:
NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。

默认handler有四个选择,当然也可以自行扩展,但是要特别小心:

  • ThreadPoolExecutor.AbortPolicy:直接抛出java.util.concurrent.RejectedExecutionException异常;
  • ThreadPoolExecutor.CallerRunsPolicy:主线程直接尝试执行该任务;当线程池中可加入时,将任务添加到线程池中;该操作会重复执行,可以有效降低主线程将任务加入到线程池的速度;
  • ThreadPoolExecutor.DiscardOldestPolicy:直接抛弃旧的任务,即把线程池内最早加入队列的线程抛弃;
  • ThreadPoolExecutor.DiscardPolicy:直接抛弃当前的任务;

再来说说java.util.concurrent.ScheduledThreadPoolExecutor ,此类是ThreadPoolExecutor的子类,所以以上我们描述的特性他都具备;除此之外,他还有一些自己特有的属性和方法:

  • schedule(Runnable command, long delay, TimeUnit unit)
    该方法创建并执行在给定延迟后启用的一次性任务;
  • scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
    该方法创建并执行一个在给定初始延迟后首次启用的定期任务,后续任务具有指定的周期;也就是将在initialDelay后开始执行,然后在initialDelay+period 后执行,接着在initialDelay + 2 * period 后执行,依此类推。
  • scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
    该方法创建并执行一个在给定初始延迟后首次启用的定期任务,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。

对于concurrent包在Spring中也进行了很多的封装,对于一些可以采用FixedRate 或者FixedDelay 来进行调度的任务,非常的方便,相比较于Quartz的实现,在配置文件方面要减少很多,有兴趣的同学可以参考Spring文档中的《第23章 Spring中的定时调度和线程池》,重点关注两个类:
org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean
org.springframework.scheduling.concurrent.ScheduledExecutorTask
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor

 

附:concurrent包中几个核心接口、类的UML类图:


知识容易遗忘,这里作为一个备份手册粘贴于此,感谢:http://www.alisdn.com/wordpress/?p=1133

分享到:
评论

相关推荐

    jdk中线程安全的集合类.docx

    ### JDK中线程安全的集合类详解 #### 1. 引言 在Java开发过程中,随着并发编程的日益普及,对于数据结构的选择也提出了更高的要求。非线程安全的数据结构如`HashMap`在高并发场景下可能会出现数据不一致等问题,这...

    jdk 1.5 线程的使用,简单例子

    通过接口java.util.concurrent.Callable 的使用 实现线程的启用,程序为一个main的例子,可以直接运行(jdk1.5 以上版本)

    JDK5中的多线程并发库.doc

    在JDK5中,Java引入了一套强大的多线程并发库,极大地提升了多线程编程的效率和安全性。这个库提供了丰富的类和接口,使得开发者能够更好地控制线程的执行、同步和通信。 1. **线程** - **线程与进程的关系**:...

    JDK1.8中文文档 JDK1.8中文 jkd8中文文档 JDK中文版

    再者,JDK1.8引入了默认方法(Default Methods)到接口中,这是一个重大的设计改变。默认方法允许在接口中定义具有实现的方法,这样可以在不破坏已有实现的情况下为接口添加新的功能。这在升级API时尤其有用,避免了...

    JDK7多线程部分类(接口)关系图

    JDK7多线程部分类(接口)关系图,根据官网得出

    JDK21虚拟线程详解.pptx.pptx

    JDK21虚拟线程,又称为Project Loom的一部分,是Java语言中引入的一项创新技术,旨在改进并发处理的效率和简化异步编程模型。虚拟线程通过轻量级的协程实现,不再依赖于操作系统的原生线程。这种设计使得在没有物理...

    jdk1.5 线程并发与线程池的使用

    线程池(ThreadPool)是一种线程使用模式,它维护了一组可重用线程,当有新的任务提交时,线程池会从现有的线程中选择一个执行任务,而不是每次都创建新的线程。这样可以减少线程创建和销毁的开销,提高系统性能。在...

    jdk17中文说明文档

    "方便已义中文方式浏览jdk中的说明"强调了这个文档是中文翻译版,使得开发者能够更轻松地理解JDK中的各种类、接口、方法和概念,降低了学习和使用的难度。 **标签解析:** "范文/模板/素材" 这个标签可能是指这个...

    JDK5中的多线程并发库

    在JDK5中,多线程并发库引入了一系列新的特性,极大地增强了Java处理并发问题的能力。以下是关于这个主题的详细解释: 1. **线程**: - **线程与进程的关系**:进程是一个正在执行的程序实体,而线程是进程内部的...

    JDK中文文档

    JDK提供了丰富的类库,涵盖了I/O、网络通信、集合框架、多线程、反射、异常处理等多个方面。文档中会详述这些类库的使用方法,例如`java.io`包用于输入输出操作,`java.net`包支持网络编程,`java.util`包包含了集合...

    jdk8中文说明文档_CHM.zip jdk1.8文档 jdk1.8说明文档

    Lambda允许将匿名函数作为参数传递,简化了多线程编程和事件处理,尤其是对集合操作的处理,如Stream API中的函数式操作。 2. **Stream API**:Stream API是Java 8中新增的一个重要组件,它提供了一种新的处理数据...

    JDK5中的并发(多线程)

    JDK 5.0 是用 Java 语言创建高可伸缩的并发应用程序的主要步骤。JVM 已经进行了改进,允许类利用硬件级别支持并发,并且提供了一组丰富的新并发构造块,使开发并发应用程序更加容易。 <br>本教程将介绍 JDK 5.0 ...

    最常用和实用的JDK内存和线程监控指令

    最常用和实用的JDK内存和线程监控指令,堆栈监控指令及操作步骤

    jdk_8中文文档

    这份"jdk api 1.8_google"文档很可能是JDK 8的API文档,详细列出了所有类、接口、方法和常量,涵盖了核心类库、集合框架、网络编程、I/O流、多线程、反射等多个方面。通过阅读这份文档,开发者可以: 1. 学习每个类...

    JDK8 中文帮助文档(jdk api 1.8 google.CHM)

    JDK8对并发库也进行了增强,如`ConcurrentHashMap`的改进,新增`AtomicIntegerArray`、`LongAdder`等原子类型,以及`ForkJoinPool`和`Parallel Streams`的引入,提高了多线程环境下的性能。 **9. Nashorn ...

    jdk8中文API文档

    下面,我们将深入探讨JDK 8中的关键知识点。 1. **Lambda表达式**: Lambda表达式是JDK 8最具代表性的新特性,它简化了函数式编程,允许开发者用更简洁的方式处理匿名函数。例如,你可以使用lambda表达式来定义...

    JDK多线程学习viso分析

    异步不用回填数据,返回页面则需要回填 Viso跨职能流程图可分析各个系统流转流程 ...当服务为对接方式的时候,判断是否有权限,有则按照数据封装传入,无权限则查询出来,再将数据放入对象模块中再传入

    JDK8 API 中文 文档.CHM

    在JDK8中,有许多关键知识点和更新,下面将详细阐述其中的重点内容: 1. **Lambda表达式**:JDK8引入了lambda表达式,这是一种简洁的匿名函数表示方式,使得函数式编程风格在Java中变得可能。Lambda表达式可以作为...

    jdk1.8 api 中文文档

    1. **Lambda表达式**:JDK 1.8引入了Lambda表达式,这是一种简洁的匿名函数写法,用于处理函数式接口,简化了多线程编程和事件处理。 2. **Stream API**:新的Stream API允许开发者对集合进行声明式处理,提供了更...

Global site tag (gtag.js) - Google Analytics