`
cuizhenfu#gmail.com
  • 浏览: 67506 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

转载 JDK1.5中的线程池使用简介

阅读更多
http://www.simplelife.cn/html/study/java/concurrent/threadPoolIn1.5.html

JDK1.5中的线程池使用简介 <!---->
<!---->

在多线程大师Doug Lea的贡献下,在JDK1.5中加入了许多对并发特性的支持,例如:线程池。这里介绍的就是1.5种的线程池的简单使用方法。
创建日期:2005-05-11
最后修改日期:2007-03-06
panhaidong@gmail.com

<!---->

一、简介
线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:

java 代码
 
  1. ThreadPoolExecutor(int corePoolSize,   
  2.                    int maximumPoolSize,   
  3.                    long keepAliveTime, TimeUnit unit,   
  4.                    BlockingQueue<runnable> workQueue,   </runnable>
  5.                    RejectedExecutionHandler handler)   

 

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

一个任务通过 execute(Runnable)方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是 Runnable类型对象的run()方法。

当一个任务通过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。

workQueue我常用的是:java.util.concurrent.ArrayBlockingQueue

handler有四个选择:
  • ThreadPoolExecutor.AbortPolicy()
    抛出java.util.concurrent.RejectedExecutionException异常
  • ThreadPoolExecutor.CallerRunsPolicy()
    重试添加当前的任务,他会自动重复调用execute()方法
  • ThreadPoolExecutor.DiscardOldestPolicy()
    抛弃旧的任务
  • ThreadPoolExecutor.DiscardPolicy()
    抛弃当前的任务

二、一般用法举例 [下载源代码]

java 代码
 
  1. package cn.simplelife.exercise;  
  2.   
  3. import java.util.concurrent.ArrayBlockingQueue;  
  4. import java.util.concurrent.ThreadPoolExecutor;  
  5. import java.util.concurrent.TimeUnit;  
  6.   
  7. public class TestThreadPool {  
  8.     private static int produceTaskSleepTime = 2;  
  9.     public static void main(String[] args) {  
  10.         //构造一个线程池  
  11.         ThreadPoolExecutor producerPool = new ThreadPoolExecutor(240,  
  12.                 TimeUnit.SECONDS, new ArrayBlockingQueue(3),  
  13.                 new ThreadPoolExecutor.DiscardOldestPolicy());  
  14.   
  15.         //每隔produceTaskSleepTime的时间向线程池派送一个任务。  
  16.         int i=1;  
  17.         while(true){  
  18.             try {  
  19.                 Thread.sleep(produceTaskSleepTime);  
  20.   
  21.                 String task = "task@ " + i;  
  22.                 System.out.println("put " + task);  
  23.   
  24.                 producerPool.execute(new ThreadPoolTask(task));  
  25.   
  26.                 i++;  
  27.             } catch (Exception e) {  
  28.                 e.printStackTrace();  
  29.             }  
  30.         }  
  31.     }  
  32. }     

java 代码
 
  1. package cn.simplelife.exercise;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. /** 
  6.  * 线程池执行的任务 
  7.  * @author hdpan 
  8.  */  
  9. public class ThreadPoolTask implements Runnable,Serializable{  
  10.       
  11.     //JDK1.5中,每个实现Serializable接口的类都推荐声明这样的一个ID  
  12.     private static final long serialVersionUID = 0;  
  13.   
  14.     private static int consumeTaskSleepTime = 2000;  
  15.     private Object threadPoolTaskData;  
  16.       
  17.     ThreadPoolTask(Object tasks){  
  18.         this.threadPoolTaskData = tasks;  
  19.     }  
  20.       
  21.     //每个任务的执行过程,现在是什么都没做,除了print和sleep,:)  
  22.     public void run(){  
  23.         System.out.println("start .."+threadPoolTaskData);  
  24.         try {  
  25.             //便于观察现象,等待一段时间  
  26.             Thread.sleep(consumeTaskSleepTime);  
  27.         } catch (Exception e) {  
  28.             e.printStackTrace();  
  29.         }  
  30.         threadPoolTaskData = null;  
  31.     }  
  32. }          


对这两段程序的说明:

  1. 在这段程序中,一个任务就是一个Runnable类型的对象,也就是一个ThreadPoolTask类型的对象。
  2. 一般来说任务除了处理方式外,还需要处理的数据,处理的数据通过构造方法传给任务。
  3. 在这段程序中,main()方法相当于一个残忍的领导,他派发出许多任务,丢给一个叫 threadPool的任劳任怨的小组来做。
    • 这个小组里面队员至少有两个,如果他们两个忙不过来, 任务就被放到任务列表里面。
    • 如果积压的任务过多,多到任务列表都装不下(超过3个)的时候,就雇佣新的队员来帮忙。但是基于成本的考虑,不能雇佣太多的队员, 至多只能雇佣 4个。
    • 如果四个队员都在忙时,再有新的任务, 这个小组就处理不了了,任务就会被通过一种策略来处理,我们的处理方式是不停的派发, 直到接受这个任务为止(更残忍!呵呵)。
    • 因为队员工作是需要成本的,如果工作很闲,闲到 3SECONDS都没有新的任务了,那么有的队员就会被解雇了,但是,为了小组的正常运转,即使工作再闲,小组的队员也不能少于两个。
  4. 通过调整 produceTaskSleepTime和 consumeTaskSleepTime的大小来实现对派发任务和处理任务的速度的控制, 改变这两个值就可以观察不同速率下程序的工作情况。
  5. 通过调整4中所指的数据,再加上调整任务丢弃策略, 换上其他三种策略,就可以看出不同策略下的不同处理方式。
  6. 对于其他的使用方法,参看jdk的帮助,很容易理解和使用。
分享到:
评论

相关推荐

    JDK1.5中的线程池

    JDK1.5中的线程池(ThreadPoolExecutor)使用简介

    jdk1.5+线程池应用

    使用jdk1.5 实现的线程池. 可以定制人物和其它特性. 下载后可以自己进行相关功能完善. 欢迎加QQ:934547801一起讨论

    jdk1.5 windows版本 64位

    泛型允许在类、接口和方法声明中使用类型参数,提供编译时类型安全并减少强制类型转换。枚举类型则为常量集合提供了更强大的支持,而增强的for循环(foreach)简化了迭代集合的操作。 6. **性能优化**: JDK 1.5的...

    jdk1.5线程池讲解

    JDK1.5的线程池讲解,示例代码,很精辟~

    jdk1.5x64位 windows版.zip

    综上所述,JDK1.5是Java发展历程中的一个重要里程碑,它的特性改进了编程体验,提升了代码质量和运行效率。而64位Windows版的JDK1.5,则是针对Windows用户的一种优化选择,满足了开发者在64位环境下的需求。文件"jdk...

    linux系统jdk1.5下载

    Linux系统中的JDK1.5是...因此,在生产环境中使用时,强烈建议升级到更现代的JDK版本,以获得更好的性能、安全性和功能支持。同时,对于学习和研究目的,理解老版本的JDK可以帮助我们更好地了解Java语言的发展历程。

    Java-jdk1.5安装包

    在JDK1.5中,开发者可以在方法签名中使用省略号(...)表示可变参数。这允许方法接受任意数量的相同类型的参数,如: ```java public void printNumbers(int... nums) { // 代码块 } ``` 这个方法可以接收一个或多...

    JDK1.5线程池源码及详细注释

    JDK 1.5引入了java.util.concurrent包,其中包含了线程池的实现,使得并发编程更加便捷和高效。线程池的核心在于它的设计策略,包括核心线程数、最大线程数、线程存活时间、工作队列以及拒绝策略。 线程池的主要类...

    JDK1.5中文帮助文档

    这个“JDK1.5中文帮助文档”是官方英文文档的中文译本,为中文用户提供了详细的解释和易于理解的指导,旨在帮助开发者更好地理解和利用JDK 1.5的新功能。** 1. **泛型(Generics)** 泛型是JDK 1.5引入的最显著的...

    JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用简介.doc

    JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用简介

    JDK1.5的32位和64位安装包

    此外,JDK1.5还引入了变长参数(Varargs)功能,允许在方法声明中使用三个点(...)表示可变长度的参数列表。这使得创建接受任意数量相同类型参数的方法变得更加简单。 在类型系统方面,JDK1.5引入了增强的for循环...

    JDK1.5,JDK1.5

    对于Java开发者来说,理解和掌握JDK1.5的这些关键特性至关重要,因为它们不仅在JDK1.5中首次出现,也成为了后续版本的基础。通过深入学习和实践,开发者能够写出更安全、更高效、更易于维护的代码。

    jdk1.5.exe jdk1.5

    jdk1.5.exe jdk1.5 jdk1.5下载

    jdk1.5免安装版

    绝版jdk1.5,非常不错的资源。用起来很好。是 Java语言对Bean类属性、事件的一种缺省处理方法。例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新 的值。通过getName/setName来访问name属性,...

    jdk1.5中文帮助文档

    4. **变量赋值检查**:编译器在JDK 1.5中增加了空指针检查,如果变量未初始化就使用,编译器会报错,增强了代码的健壮性。 5. **for-each循环**:新的增强for循环(也称为foreach循环)让遍历数组和集合变得更加...

    jdk 1.5 中文 api chm

    jdk 1.5 中文 api chm jdk 1.5 中文 api chm

    详细介绍JDK1.5的各种新特性

    以下是JDK1.5中的主要新特性及其详细解释: 1. **泛型(Generics)**:泛型是JDK1.5引入的最大变革之一。它允许在类、接口和方法中使用类型参数,提高了代码的类型安全性和重用性。泛型帮助程序员在编译时检查类型...

    简单易用通用(xls,xlsx)导入导出操作 jdk1.5+

    前几天上传过这个资源,因为是在jdk1.6上开发的, 测试了一下在jdk1.5上不能用, 今天重新用jdk1.5编译了一下, 这个是可以支持jdk1.5+的 将 pu-xlscommon-1.0.0.jar 添加到工程的 /lib 目录下 用法在附件中 XlsTest....

    包含 jdk1.5免安装、jdk1.6免安装、jdk1.8(32和64)

    这个压缩包包含了三个不同版本的JDK:JDK 1.5、JDK 1.6和JDK 1.8,其中1.5和1.6是早期版本,而1.8是最流行且广泛使用的版本之一。 **JDK 1.5(也称为Java 5.0)** JDK 1.5在2004年发布,引入了许多重要的新特性,如...

    window JDK1.5 32位 绿色免安装版,可以安装多个JDK使用

    标题中的"window JDK1.5 32位 绿色免安装版"指的是适用于Windows操作系统的32位版本的JDK 1.5,它是一个便携式版本,无需正式安装即可使用。这种绿色免安装版通常是为了方便开发者在不同机器间快速切换工作环境,或...

Global site tag (gtag.js) - Google Analytics