- 浏览: 141950 次
- 来自: ...
-
文章分类
最新评论
-
nocb:
太感谢了, 我调了2天,始终找不到原因,
DataOutputStream writeBytes(String s) 中文乱码--ZT -
jbeduhai:
发贴能成功吗,我执行的怎么是说没有登录呢,前面登录是正常的,发 ...
ZT---httpclient如何保持session会话模拟登录后的操作 -
chwanga:
很详细啊,廓然开朗,感谢楼主
filter servlet 区别--ZT -
JMS_Exception:
xvm03 写道promzaid 写道.net 还是 java ...
Java的字符流和字节流 -
xvm03:
promzaid 写道.net 还是 java java
Java的字符流和字节流
JDK1.5中的线程池使用简介
在多线程大师Doug Lea的贡献下,在JDK1.5中加入了许多对并发特性的支持,例如:线程池。这里介绍的就是1.5种的线程池的简单使用方法。
一、简介
线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, 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()
抛弃当前的任务
二、一般用法举例
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(1, 1, 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();
}
}
}
}
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中所指的数据,再加上调整任务丢弃策略, 换上其他三种策略,就可以看出不同策略下的不同处理方式。
发表评论
-
页面弹出登录框如何通过httpclient进行登录
2011-01-04 16:17 1336页面弹出登录框如何通过httpclient进行登录 h ... -
转贴--在Struts2的Action中取得请求参数值的几种方法
2010-10-27 18:33 1189在Struts2的Action中取得请求参数值的几 ... -
jdbc连接
2010-08-02 17:43 720Connection conn = null; ResultS ... -
几个需要仔细阅读的源码
2010-05-19 23:20 698OSGI spring jboss -
listener,filter区别--ZT
2010-04-28 16:05 1670web.xml里面可以配置Filter和Listen ... -
JDK 1.4中存在一个有关编--ZT
2010-04-23 21:30 1022在JDK 1.4中存在一个有关编码的问题。简要描述如下: ... -
Servlet不是单例的--ZT
2010-04-22 20:59 1879Servlet不是单例的.不过一般来说一个servlet只会有 ... -
java 多态的理解--ZT
2010-04-18 00:43 1068如何理解Java多态性?通过类型转换,把一个对 ... -
JAVA 深入学习
2010-04-17 14:37 797java 设计模式:策略模式(内部类的使用),装饰模式(IO) ... -
JAVA和JAVAC 命令行--ZZ
2009-09-27 15:45 837JAVA和JAVAC 命令行 ... -
jbpm工作流入门教程
2009-09-27 11:36 1926jbpm工作流入门教程 ... -
工作流学习-JBPM(一)
2009-09-27 11:25 791展翅飞翔 致力于J2EE与中间件整合方面的研 ... -
详细解析Java中抽象类和接口的区别
2009-03-03 20:38 665详细解析Java中抽象类和 ... -
比较Vector和ArrayList的不同
2009-03-03 20:35 1197――比较Vector和ArrayLi ... -
string,stringbuffer,stringbuilder比较
2009-03-03 20:33 1214出于方便的考虑,我们在进行字符串的内容处理的时候往往会 ... -
java面向对象浅析系列2
2009-03-03 20:21 681java面向对象浅析系列2——抽象类、接口与多继承 有时 ... -
java面向对象浅析系列1
2009-03-03 20:21 710java面向对象浅析系列1 ... -
一个JDBC简单连接
2009-03-03 20:04 701一个最基本的JDBC连接: Conn ... -
为什么要使用泛型?
2009-03-03 19:59 1464类型安全的List Java的一 ... -
泛型的注意事项
2009-03-03 19:58 9421、不可以用一个本地类 ...
相关推荐
这篇文章结合Doug Lea大神在JDK1.5提供的JCU包,分别从线程池大小参数的设置、工作线程的创建、空闲线程的回收、阻塞队列的使用、任务拒绝策略、线程池Hook等方面来了解线程池的使用,其中涉及到一些细节包括不同...
简单的JAVA HTML服务器 实现原理为采用Socket原理、线程池、输入输出流及简单的HTTP协议...JAR编译的JDK版本1.6,至少要JDK1.5以上,因为其中用到JDK自带的线程池,内附源码,用户可以自已将源码再打包。 下载路径为:
(1)制作一个简单的面板 JFrame,文件保存为 bollFrame.java,其中为一个 public 的类 bollFrame,其构造方法为:bollFrame(int n) { ... }。 (2)构造画板类,文件保存为 bollPanel.java,其构造函数如下:...
1.5 java源文件编排格式 代码行长度与折行规则 1.6 程序注释 1.7 变量的声明初始化与放置 1.7.1 变量声明 1.7.2 变量初始化 1.7.3 变量放置 1.8 java程序语句编写规则 1.8.1 简单语句 1.8.2 复合语句 1.9 空格与空行...
《Java 7并发编程实战手册》是Java 7并发编程的实战指南,介绍了Java 7并发API中大部分重要而有用的机制。全书分为9章,涵盖了线程管理、线程同步、线程执行器、Fork/Join框架、并发集合、定制并发类、测试并发应用...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
5.java 中的 Math.round(-1.5) 等于多少? 6.String 属于基础的数据类型吗? 7.java 中操作字符串都有哪些类?它们之间有什么区别? 8.String str="i"与 String str=new String(“i”)一样吗? 9.如何将字符串反转?...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
1.5 第一个Java程序 12 1.5.1 编辑Java源代码 12 1.5.2 编译Java程序 13 学生提问:当我们使用编译C程序时,不仅需要指定存放目标文件的位置,也需要指定目标文件的文件名,这里使用javac编译Java程序时怎么不...
全部代码出自电子工业出版社夏先波的《Java JDK实例宝典》一书,本书以J2SE 5.0为开发环境,选取Java应用的典型实例,循序渐进地介绍了Java语言的各种开发方法和技巧,实例代码注释详细规范,思路清晰。 第1章 ...
5. java 中的 Math.round(-1.5) 等于多少? 4 6. String 属于基础的数据类型吗? 4 7. java 中操作字符串都有哪些类?它们之间有什么区别? 4 8. String str="i"与 String str=new String("i")一样吗? 5 9. 如何将...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...
内容简介回到顶部↑《Java网络编程》第三版会为你介绍Java网络API的最新特性。本书讨论了JDK 1.4和1.5(现在已命名为J2SE 5)中所做的所有修改和增补。本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各...