`
xiaomao1027
  • 浏览: 9907 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

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

    博客分类:
  • java
阅读更多

JDK1.5中的线程池使用简介 在多线程大师Doug Lea的贡献下,在JDK1.5中加入了许多对并发特性的支持,例如:线程池。这里介绍的就是1.5种的线程池的简单使用方法。

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

java 代码

ThreadPoolExecutor(int corePoolSize,   
                   int maximumPoolSize,   
                   long keepAliveTime, TimeUnit unit,   
                   BlockingQueue<runnable> workQueue,   </runnable>
                   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 代码

package cn.simplelife.exercise;  
  
import java.util.concurrent.ArrayBlockingQueue;  
import java.util.concurrent.ThreadPoolExecutor;  
import java.util.concurrent.TimeUnit;  
  
public class TestThreadPool {  
    private static int produceTaskSleepTime = 2;  
    public static void main(String[] args) {  
        //构造一个线程池  
        ThreadPoolExecutor producerPool = new ThreadPoolExecutor(2, 4, 0,  
                TimeUnit.SECONDS, new ArrayBlockingQueue(3),  
                new ThreadPoolExecutor.DiscardOldestPolicy());  
  
        //每隔produceTaskSleepTime的时间向线程池派送一个任务。  
        int i=1;  
        while(true){  
            try {  
                Thread.sleep(produceTaskSleepTime);  
  
                String task = "task@ " + i;  
                System.out.println("put " + task);  
  
                producerPool.execute(new ThreadPoolTask(task));  
  
                i++;  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    }  
}     


java 代码

package cn.simplelife.exercise;  
  
import java.io.Serializable;  
  
/** 
* 线程池执行的任务 
* @author hdpan 
*/  
public class ThreadPoolTask implements Runnable,Serializable{  
      
    //JDK1.5中,每个实现Serializable接口的类都推荐声明这样的一个ID  
    private static final long serialVersionUID = 0;  
  
    private static int consumeTaskSleepTime = 2000;  
    private Object threadPoolTaskData;  
      
    ThreadPoolTask(Object tasks){  
        this.threadPoolTaskData = tasks;  
    }  
      
    //每个任务的执行过程,现在是什么都没做,除了print和sleep,:)  
    public void run(){  
        System.out.println("start .."+threadPoolTaskData);  
        try {  
            //便于观察现象,等待一段时间  
            Thread.sleep(consumeTaskSleepTime);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        threadPoolTaskData = null;  
    }  
}          


对这两段程序的说明:

在这段程序中,一个任务就是一个Runnable类型的对象,也就是一个ThreadPoolTask类型的对象。
一般来说任务除了处理方式外,还需要处理的数据,处理的数据通过构造方法传给任务。
在这段程序中,main()方法相当于一个残忍的领导,他派发出许多任务,丢给一个叫 threadPool的任劳任怨的小组来做。

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

 

分享到:
评论

相关推荐

    JDK1.5中的线程池

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

    jdk1.5+线程池应用

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

    jdk1.5线程池讲解

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

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

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

    jdk jdk1.5 windows系统

    10. **NIO.2(New IO 2.0)**:虽然不是JDK1.5的一部分,但在后续的Java版本中,NIO(非阻塞I/O)进行了大量增强,增加了文件通道、文件属性和异步I/O等功能。 11. **异常链(Exception Chaining)**:当一个异常在...

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

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

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

    "JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用" JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用是Java多线程编程中的一种重要概念。随着多线程编程的普及,线程池的使用变得...

    jdk1.5 windows 64位官方正式版,绝对有效

    对于并发编程,JDK1.5引入了java.util.concurrent包,其中包括了线程池、Future、Callable接口以及CyclicBarrier和Semaphore等同步工具类,极大地丰富了并发处理能力,提升了多线程环境下的性能和可维护性。...

    jdk1.5 64位 免安装

    在并发处理上,JDK1.5引入了并发工具类(java.util.concurrent),包括线程池(ExecutorService)、并发容器(如ConcurrentHashMap)以及Future接口等,这些工具极大地提高了多线程环境下的程序设计效率和性能。...

    jdk1.5 for windows32 安装包

    泛型是JDK 1.5最重要的特性之一,它允许在类、接口和方法中使用类型参数,提高了代码的类型安全性和重用性。这减少了强制类型转换的需要,降低了因类型不匹配而引发的错误。 2. **枚举(Enums)** JDK 1.5引入了...

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

    在Java编程语言中,线程并发和线程池是多任务执行的核心概念,尤其是在JDK 1.5及以后的版本中得到了显著增强。线程并发允许程序同时执行多个任务,提高了程序的效率和响应性。线程池是管理线程资源的有效方式,通过...

    jdk1.5 and tomcat5.5

    标题"jdk1.5 and tomcat5.5"指的是Java Development Kit (JDK) 1.5版本与Apache Tomcat 5.5版本的组合。这两个组件是开发和运行Java应用程序的关键工具,特别是对于Web应用程序。 描述中提到的"jdk-1_5_0_22-...

    JDK1.5免安装

    泛型是Java 5引入的一个关键特性,允许在类、接口和方法中使用类型参数,提高了代码的类型安全性,减少了强制类型转换,同时提升了代码的可读性和重用性。 2. **枚举(Enums)** JDK1.5引入了枚举类型,这是一种...

    官方JDK1.5版本

    3. 静态导入(Static Import):允许开发者直接使用类中的静态成员,而无需通过类名来引用,减少了冗余代码。 4. 枚举(Enums):枚举类型提供了一种声明固定数量的常量的机制,增强了代码的可读性和安全性。 5. ...

    jdk1.5 64位

    `使用说明.txt`可能包含的是安装和配置JDK 1.5的步骤,包括设置环境变量、验证安装等关键信息。对于初学者来说,这是一个重要的指南。 `安卓游戏下载.url`和`单机游戏下载.url`以及`更多软件点击进入.url`似乎与JDK...

    jdk1.5.0.22 64位

    **Java Development Kit (JDK)...总之,JDK 1.5.0.22 64位是一个重要的历史版本,它在Java发展历程中扮演了关键角色,引入了许多至今仍广泛使用的特性。然而,为了保持软件的最新特性和安全性,建议使用更新的JDK版本。

    jdk1.5安装包

    以上就是JDK 1.5中的一些关键特性,这些改变对Java语言的发展产生了深远影响,使得Java成为更强大、更易用的开发平台。如果你正准备安装JDK 1.5,记得检查系统兼容性,遵循官方的安装指南进行操作。

    jdk1.5并发新特性.

    这些并发新特性使得在 JDK 1.5 中编写多线程程序变得更加简单和高效,减少了锁竞争,提高了并发性能,并降低了死锁和数据不一致的风险。通过熟练掌握这些工具,开发者可以更好地应对复杂的并发场景,构建健壮的并发...

    jdk1.5.0_17 for windows

    3. **枚举类型**:JDK 1.5增加了枚举类型,使得枚举常量更加安全且易于使用,避免了使用整数常量来表示枚举的不安全和混乱。 4. **变量注入**:通过`@`注解,可以向字段、方法或类添加元数据,增强了代码的可读性...

    JDK1.5和Tomcat5.5.9.rar

    在本例中,我们讨论的是JDK1.5和Tomcat5.5.9的组合,这是一个较旧的技术栈,但仍然可能在某些公司的遗留系统中使用。 **JDK1.5** JDK1.5,也称为Java SE 5.0,于2004年发布。它是Java发展历程中的一个重要里程碑,...

Global site tag (gtag.js) - Google Analytics