- 浏览: 351720 次
- 性别:
- 来自: 成都正在项目
文章分类
- 全部博客 (121)
- Java-Spring (1)
- Java-Hibernate (5)
- Java-基础 (16)
- Java-中级 (1)
- Java-高级 (18)
- Java-Struts (0)
- Java-RCP/Swing/SWT/JFACE (1)
- Java-常用正则 (1)
- Java-反射 (2)
- Java-h2database (2)
- JAVA面试题目 (1)
- ArcGIS Desktop 10——安装篇 (2)
- ArcGIS Desktop 10——基本知识 (0)
- ArcGIS Desktop 10——专业库——数据管理 (9)
- PHP——安装篇 (3)
- PHP——基础篇 (2)
- PHP——教程笔记 (10)
- GIS——基础 (3)
- GIS——算法 (0)
- GIS——Geoserver (1)
- GIS——OpenLayers (1)
- C#——既然改成了ITEYE我就增加个栏目 (1)
- Oracle——PL/SQL (1)
- Oracle——Java基础 (2)
- Oracle——TOAD (1)
- ECLIPSE-MYECLIPSE常见问题 (3)
- MySQL——安装篇 (4)
- Postgres (5)
- JavaScript - JQUERY (2)
- C++ (2)
- 操作系统 (5)
- Dwr——DirectWebRemoting (5)
- Maven (1)
- FLEX (4)
- ruby (1)
最新评论
-
AXthrough:
好强大,支持。
解决Jquery.autocomplete.js多参数的正确传递+中文编码+发送兼容FF+空格问题+返回值 -
redsky008:
独立的程序,独立的路径。
我已经转行了,以后这个很少关注的了 ...
真正解决 log4j:ERROR Failed to rename错误解决办法 -
梅花簪:
没明白,怎么改配置,为不同的进程所有?
真正解决 log4j:ERROR Failed to rename错误解决办法
将封装的如下方法置顶
遇到多线程问题了,有个比较简单的方法做线程池,如下。
转自:http://blog.csdn.net/robage/archive/2007/05/22/1620691.aspx
在多线程大师Doug Lea的贡献下,在JDK1.5中加入了许多对并发特性的支持,例如:线程池。
一、简介
线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
corePoolSize: 线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
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()
抛弃当前的任务
二、一般用法举例
//------------------------------------------------------------
//TestThreadPool.java
//package cn.simplelife.exercise;
import java.io.Serializable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TestThreadPool {
private static int produceTaskSleepTime = 2;
private static int consumeTaskSleepTime = 2000;
private static int produceTaskMaxNumber = 10;
public static void main(String[] args) {
//构造一个线程池
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),
new ThreadPoolExecutor.DiscardOldestPolicy());
for(int i=1;i<=produceTaskMaxNumber;i++){
try {
//产生一个任务,并将其加入到线程池
String task = "task@ " + i;
System.out.println("put " + task);
threadPool.execute(new ThreadPoolTask(task));
//便于观察,等待一段时间
Thread.sleep(produceTaskSleepTime);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 线程池执行的任务
* @author hdpan
*/
public static class ThreadPoolTask implements Runnable,Serializable{
private static final long serialVersionUID = 0;
//保存任务所需要的数据
private Object threadPoolTaskData;
ThreadPoolTask(Object tasks){
this.threadPoolTaskData = tasks;
}
public void run(){
//处理一个任务,这里的处理方式太简单了,仅仅是一个打印语句
System.out.println("start .."+threadPoolTaskData);
try {
////便于观察,等待一段时间
Thread.sleep(consumeTaskSleepTime);
} catch (Exception e) {
e.printStackTrace();
}
threadPoolTaskData = null;
}
public Object getTask(){
return this.threadPoolTaskData;
}
}
}
//------------------------------------------------------------
说明:
1、在这段程序中,一个任务就是一个Runnable类型的对象,也就是一个ThreadPoolTask类型的对象。
2、一般来说任务除了处理方式外,还需要处理的数据,处理的数据通过构造方法传给任务。
3、在这段程序中,main()方法相当于一个残忍的领导,他派发出许多任务,丢给一个叫 threadPool的任劳任怨的小组来做。
这个小组里面队员至少有两个,如果他们两个忙不过来,任务就被放到任务列表里面。
如果积压的任务过多,多到任务列表都装不下(超过3个)的时候,就雇佣新的队员来帮忙。但是基于成本的考虑,不能雇佣太多的队员,至多只能雇佣 4个。
如果四个队员都在忙时,再有新的任务,这个小组就处理不了了,任务就会被通过一种策略来处理,我们的处理方式是不停的派发,直到接受这个任务为止(更残忍!呵呵)。
因为队员工作是需要成本的,如果工作很闲,闲到 3SECONDS都没有新的任务了,那么有的队员就会被解雇了,但是,为了小组的正常运转,即使工作再闲,小组的队员也不能少于两个。
4、通过调整 produceTaskSleepTime和 consumeTaskSleepTime的大小来实现对派发任务和处理任务的速度的控制,改变这两个值就可以观察不同速率下程序的工作情况。
5、通过调整4中所指的数据,再加上调整任务丢弃策略,换上其他三种策略,就可以看出不同策略下的不同处理方式。
6、对于其他的使用方法,参看jdk的帮助,很容易理解和使用。
public static ThreadPoolExecutor newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } public static ThreadPoolExecutor newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
遇到多线程问题了,有个比较简单的方法做线程池,如下。
转自:http://blog.csdn.net/robage/archive/2007/05/22/1620691.aspx
在多线程大师Doug Lea的贡献下,在JDK1.5中加入了许多对并发特性的支持,例如:线程池。
一、简介
线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
corePoolSize: 线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
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()
抛弃当前的任务
二、一般用法举例
//------------------------------------------------------------
//TestThreadPool.java
//package cn.simplelife.exercise;
import java.io.Serializable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TestThreadPool {
private static int produceTaskSleepTime = 2;
private static int consumeTaskSleepTime = 2000;
private static int produceTaskMaxNumber = 10;
public static void main(String[] args) {
//构造一个线程池
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),
new ThreadPoolExecutor.DiscardOldestPolicy());
for(int i=1;i<=produceTaskMaxNumber;i++){
try {
//产生一个任务,并将其加入到线程池
String task = "task@ " + i;
System.out.println("put " + task);
threadPool.execute(new ThreadPoolTask(task));
//便于观察,等待一段时间
Thread.sleep(produceTaskSleepTime);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 线程池执行的任务
* @author hdpan
*/
public static class ThreadPoolTask implements Runnable,Serializable{
private static final long serialVersionUID = 0;
//保存任务所需要的数据
private Object threadPoolTaskData;
ThreadPoolTask(Object tasks){
this.threadPoolTaskData = tasks;
}
public void run(){
//处理一个任务,这里的处理方式太简单了,仅仅是一个打印语句
System.out.println("start .."+threadPoolTaskData);
try {
////便于观察,等待一段时间
Thread.sleep(consumeTaskSleepTime);
} catch (Exception e) {
e.printStackTrace();
}
threadPoolTaskData = null;
}
public Object getTask(){
return this.threadPoolTaskData;
}
}
}
//------------------------------------------------------------
说明:
1、在这段程序中,一个任务就是一个Runnable类型的对象,也就是一个ThreadPoolTask类型的对象。
2、一般来说任务除了处理方式外,还需要处理的数据,处理的数据通过构造方法传给任务。
3、在这段程序中,main()方法相当于一个残忍的领导,他派发出许多任务,丢给一个叫 threadPool的任劳任怨的小组来做。
这个小组里面队员至少有两个,如果他们两个忙不过来,任务就被放到任务列表里面。
如果积压的任务过多,多到任务列表都装不下(超过3个)的时候,就雇佣新的队员来帮忙。但是基于成本的考虑,不能雇佣太多的队员,至多只能雇佣 4个。
如果四个队员都在忙时,再有新的任务,这个小组就处理不了了,任务就会被通过一种策略来处理,我们的处理方式是不停的派发,直到接受这个任务为止(更残忍!呵呵)。
因为队员工作是需要成本的,如果工作很闲,闲到 3SECONDS都没有新的任务了,那么有的队员就会被解雇了,但是,为了小组的正常运转,即使工作再闲,小组的队员也不能少于两个。
4、通过调整 produceTaskSleepTime和 consumeTaskSleepTime的大小来实现对派发任务和处理任务的速度的控制,改变这两个值就可以观察不同速率下程序的工作情况。
5、通过调整4中所指的数据,再加上调整任务丢弃策略,换上其他三种策略,就可以看出不同策略下的不同处理方式。
6、对于其他的使用方法,参看jdk的帮助,很容易理解和使用。
发表评论
-
RESTEasy 例子 hello world(两种方法)
2012-12-14 17:41 21865转载自http://zorro.blog.51cto.com/ ... -
原来Junit不支持多线程测试,需要使用GroboUtils才可以支持多线程测试
2011-12-06 09:30 1950对Junit的不深刻理解,造成多线程执行不完整,比如执行100 ... -
java.lang.LinkageError: JAXB 2.0 API is being loaded from the bootstrap classloa
2011-07-29 10:07 1273在做RESTful测试时,在Windows系统下出现了如下问题 ... -
转:Mina2 Http server
2011-07-27 14:03 1047http://amozon.iteye.com/blog/32 ... -
Base64测试
2011-06-29 17:36 1package com.redsky.cn.test; ... -
转Java集群好网站
2011-06-28 22:11 717http://www.jdon.com/jivejdon/th ... -
转:常见NIO开源框架(MINA、xSocket)学习 2
2011-06-23 18:17 841http://unbounder.iteye.com/blog ... -
test
2011-06-23 16:50 544http://www.liuyangs.info/docume ... -
转:直接用socket的话,mina server就不能用filter
2011-06-23 16:00 1转:http://www.blogjava.net/cresp ... -
转:模拟Mina2的TextLineCodecFactory中的TextLineDecoder解码器
2011-06-21 21:50 2001转自:http://hi.baidu.com/huahua03 ... -
转Java NIO文件操作
2011-06-21 13:54 907http://download.csdn.net/source ... -
搜集的一篇OutOfMemoryError
2011-06-10 23:29 1967最近遇到如下问题,主要是在做线程池+数据库连接池时遇到的,虽然 ... -
另一个线程池ThreadPool,感觉比之前发的那个JDK自带的好用
2011-06-10 22:52 2248import java.util.LinkedList; p ... -
转载Socket解包
2011-05-31 20:04 1836http://liuyuyuan.iteye.com/blog ... -
Java解决常见验证码——一定是准确率100%
2011-05-28 21:30 1146绝对不适合于严重扭曲,形状交叉的情形。有别于传统切图(一般4张 ... -
Mina2和Spring(2.5)在web项目中的结合使用
2011-05-18 20:55 783转载http://yanda20056.blog.163.co ... -
学习动态代理的时候,原来JAVA代码中也可以编译代码执行JAVAC的功能啊
2011-05-04 22:37 1026JDK1.6提供了如题的功能,前提是项目必须引入JDK1.6而 ... -
关于Map接口中Key值是对象还是值的问题
2011-04-28 19:24 3653今天遇到取不出Key所对应的值,取值为null. 原来是Key ... -
深度克隆对象
2011-04-28 15:10 1024必须将对象序列和反序列, 而且尤其在多线程中要引用多个对象,而 ...
相关推荐
"JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用" JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用是Java多线程编程中的一种重要概念。随着多线程编程的普及,线程池的使用变得...
JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用简介
JDK 1.5引入了java.util.concurrent包,其中包含了线程池的实现,使得并发编程更加便捷和高效。线程池的核心在于它的设计策略,包括核心线程数、最大线程数、线程存活时间、工作队列以及拒绝策略。 线程池的主要类...
在Java中,`java.util.concurrent`包中的`ThreadPoolExecutor`是线程池的主要实现。 **ThreadPoolExecutor的使用** `ThreadPoolExecutor`包含以下几个关键参数: 1. **corePoolSize**:核心线程数,即使没有任务,...
4. **多线程**:`java.lang.Thread`和`java.util.concurrent`包中的类,如`ExecutorService`、`ThreadPoolExecutor`等,展示了如何实现并发和异步执行。 5. **反射机制**:`java.lang.reflect`包中的类,如`Class`...
JDK 自带线程池是 Java 语言中用于管理和执行线程的工具,旨在提高多线程编程的效率和灵活性。本文将详细介绍 JDK 自带线程池的组成、创建方法、优点和常见应用场景。 多线程技术 多线程技术是指在一个处理器单元...
《backport-util-concurrent:Java并发编程的利器》 在Java的世界里,高效并发处理是提升应用程序性能的关键因素之一。backport-util-concurrent库,正如其名,是一种将Java 5及以上版本的并发特性“回移植”到Java...
在JDK 1.5版本之前,Java对线程池的支持非常有限,而在JDK 1.5之后,加入了java.util.concurrent包,其中包含了一系列关于线程池的接口和类,极大地丰富了线程池的应用场景和管理方式。 线程池的主要作用是限制系统...
2. **包**:Java使用包来组织类,比如`java.util`包包含了集合框架、日期时间处理、I/O流等功能。 3. **异常处理**:`java.lang.Throwable`类及其子类如`Exception`和`Error`,提供了异常处理机制。 ### 二、集合...
线程池的引入始于JDK 1.5,它引入了`java.util.concurrent`包,提供了`Executor`、`ExecutorService`和相关的实现类,如`ThreadPoolExecutor`和`ScheduledThreadPoolExecutor`。 线程池的主要作用是限制系统中同时...
首先,Java中的线程池设计始于JDK 5.0,主要通过`java.util.concurrent`包中的`Executor`接口实现。这个接口仅有一个`execute()`方法,用于提交执行任务。我们也将遵循这个设计,实现一个简单的线程池类`...
Java并发包源码分析(JDK1.8):囊括了java.util.concurrent包中大部分类的源码分析,其中涉及automic包,locks包(AbstractQueuedSynchronizer、ReentrantLock、ReentrantReadWriteLock、LockSupport等),queue...
线程池在Java中是通过`java.util.concurrent`包下的`ThreadPoolExecutor`类实现的。 线程池的主要作用是限制系统中执行线程的数量,通过预先配置好的线程数量,可以避免过多线程导致的资源浪费和系统拥挤,从而提高...
6. **多线程**:Java内置对多线程的支持,`java.lang.Thread`类和`java.util.concurrent`包提供了创建和管理线程的工具,如`Runnable`接口,`ExecutorService`,`Future`和`Callable`等。 7. **网络编程**:`java...
Java中,线程池是通过java.util.concurrent.ThreadPoolExecutor类实现的,它为Java应用程序提供了一种有效地管理线程资源的方式。从JDK 1.5开始,Java并发API得到了增强,提供了更为强大的并发工具和库,其中就包括...
然而,自JDK 1.5开始,随着`java.util.concurrent`包的引入,Java线程池的功能得到了极大的增强,为开发者提供了更加高效且易于管理的线程管理方式。 #### 二、线程池的作用与必要性 线程池的主要功能在于限制系统...
我们可以扩展`java.util.concurrent.ThreadPoolExecutor`类,它提供了更复杂的线程池管理功能,包括工作队列、核心线程数、最大线程数等参数。 3. JDK 中的线程池和工作机制 JDK内置了多种线程池实现,如`...
以`java.util.concurrent`包为例,该包提供了许多用于管理并发任务的类,比如`ExecutorService`接口和其实现类`ThreadPoolExecutor`。下面是一个简单的示例: ```java import java.util.concurrent.Executors; ...
8. **并发和多线程**:OpenJDK8的源码中,`java.util.concurrent`包下包含了丰富的并发工具类,如`ExecutorService`, `Semaphore`, `CountDownLatch`等,以及线程池的实现`ThreadPoolExecutor`。 9. **Garbage ...
Java.util.concurrent包是JDK5引入的一个重要更新,它包含了Doug Lea设计的并发库,极大地提升了Java处理并发的能力。这个库提供了高效且易用的多线程工具,包括线程池、同步器和定时任务管理等。 线程池是Java多...