线程池通俗的描述就是预先创建若干空闲线程 等到需要用多线程去处理事务的时候去唤醒某些空闲线程执行处理任务 这样就省去了频繁创建线程的时间 因为频 繁创建线程是要耗费大量的CPU资源的 如果一个应用程序需要频繁地处理大量并发事务 不断的创建销毁线程往往会大大地降低系统的效率 这时候线程池就派 上用场了
本文旨在使用Java语言编写一个通用的线程池 当需要使用线程池处理事务时 只需按照指定规范封装好事务处理对象 然后用已有的线程池对象去自动选择空 闲线程自动调用事务处理对象即可 并实现线程池的动态修改(修改当前线程数 最大线程数等) 下面是实现代码
//ThreadTask java
package polarman threadpool
/** *//**
*线程任务
* @author ryang
*
*/
public interface ThreadTask {
public void run()
}
//PooledThread java
package polarman threadpool
import java util Collectionimport java util Vector
/** *//**
*接受线程池管理的线程
* @author ryang
*
*/
public class PooledThread extends Thread {
protected Vector tasks = new Vector()
protected boolean running = false
protected boolean stopped = false
protected boolean paused = false
protected boolean killed = false
private ThreadPool pool
public PooledThread(ThreadPool pool) { this pool = pool
}
public void putTask(ThreadTask task) { tasks add(task)
}
public void putTasks(ThreadTask[] tasks) { for(int i= i<tasks lengthi++) this tasks add(tasks[i])
}
public void putTasks(Collection tasks) { this tasks addAll(tasks)
}
protected ThreadTask popTask() { if(tasks size() >) return (ThreadTask)tasks remove( )
else
return null
}
public boolean isRunning() {
return running
}
public void stopTasks() {
stopped = true
}
public void stopTasksSync() {
stopTasks()
while(isRunning()) { try {
sleep( )
} catch (InterruptedException e) {
}
}
}
public void pauseTasks() {
paused = true
}
public void pauseTasksSync() {
pauseTasks()
while(isRunning()) { try {
sleep( )
} catch (InterruptedException e) {
}
}
}
public void kill() { if(!running)
interrupt()
else
killed = true
}
public void killSync() {
kill()
while(isAlive()) { try {
sleep( )
} catch (InterruptedException e) {
}
}
}
public synchronized void startTasks() {
running = true
this notify()
}
public synchronized void run() { try { while(true) { if(!running || tasks size() == ) { pool notifyForIdleThread()//System out println(Thread currentThread() getId() + : 空闲 )this wait()}else {
ThreadTask task
while((task = popTask()) != null) { task run()if(stopped) {
stopped = false
if(tasks size() >) { tasks clear()System out println(Thread currentThread() getId() + : Tasks are stopped )
break
}
}
if(paused) {
paused = false
if(tasks size() >) { System out println(Thread currentThread() getId() + : Tasks are paused )
break
}
}
}
running = false
}
if(killed) {
killed = false
break
}
}
}catch(InterruptedException e) {
return
}
//System out println(Thread currentThread() getId() + : Killed )
}
}
//ThreadPool java
package polarman threadpool
import java util Collectionimport java util Iteratorimport java util Vector
/** *//**
*线程池
* @author ryang
*
*/
public class ThreadPool {
protected int maxPoolSize
protected int initPoolSize
protected Vector threads = new Vector()
protected boolean initialized = false
protected boolean hasIdleThread = false
public ThreadPool(int maxPoolSize int initPoolSize) { this maxPoolSize = maxPoolSizethis initPoolSize = initPoolSize
}
public void init() {
initialized = true
for(int i= i<initPoolSizei++) {
PooledThread thread = new PooledThread(this)
thread start()threads add(thread)
}
//System out println( 线程池初始化结束 线程数= + threads size() + 最大线程数= + maxPoolSize)
}
public void setMaxPoolSize(int maxPoolSize) { //System out println( 重设最大线程数 最大线程数= + maxPoolSize)this maxPoolSize = maxPoolSize
if(maxPoolSize <getPoolSize())
setPoolSize(maxPoolSize)
}
/** *//**
*重设当前线程数
* 若需杀掉某线程 线程不会立刻杀掉 而会等到线程中的事务处理完成* 但此方法会立刻从线程池中移除该线程 不会等待事务处理结束
* @param size
*/
public void setPoolSize(int size) { if(!initialized) {
initPoolSize = size
return
}else if(size >getPoolSize()) { for(int i=getPoolSize()i<size &&i<maxPoolSizei++) {
PooledThread thread = new PooledThread(this)
thread start()threads add(thread)
}
}else if(size <getPoolSize()) { while(getPoolSize() >size) { PooledThread th = (PooledThread)threads remove( )th kill()
}
}
//System out println( 重设线程数 线程数= + threads size())
}
public int getPoolSize() { return threads size()
}
protected void notifyForIdleThread() {
hasIdleThread = true
}
protected boolean waitForIdleThread() {
hasIdleThread = false
while(!hasIdleThread &&getPoolSize() >= maxPoolSize) { try { Thread sleep( )} catch (InterruptedException e) {
return false
}
}
return true
}
public synchronized PooledThread getIdleThread() { while(true) { for(Iterator itr=erator()itr hasNext()) { PooledThread th = (PooledThread)itr next()if(!th isRunning())
return th
}
if(getPoolSize() <maxPoolSize) {
PooledThread thread = new PooledThread(this)
thread start()threads add(thread)
return thread
}
//System out println( 线程池已满 等待 )
if(waitForIdleThread() == false)
return null
}
}
public void processTask(ThreadTask task) {
PooledThread th = getIdleThread()
if(th != null) { th putTask(task)th startTasks()
}
}
public void processTasksInSingleThread(ThreadTask[] tasks) {
PooledThread th = getIdleThread()
if(th != null) { th putTasks(tasks)th startTasks()
}
}
public void processTasksInSingleThread(Collection tasks) {
PooledThread th = getIdleThread()
if(th != null) { th putTasks(tasks)th startTasks()
}
}
}
下面是线程池的测试程序
//ThreadPoolTest java
import java io BufferedReaderimport java io IOExceptionimport java io InputStreamReader
import polarman threadpool ThreadPoolimport polarman threadpool ThreadTask
public class ThreadPoolTest {
public static void main(String[] args) { System out println( quit 退出 )System out println( task A 启动任务A 时长为 秒 )System out println( size 设置当前线程池大小为 )System out println( max 设置线程池最大线程数为 )System out println()
final ThreadPool pool = new ThreadPool( )pool init()
Thread cmdThread = new Thread() { public void run() {
BufferedReader reader = new BufferedReader(new InputStreamReader(System in))
while(true) { try { String line = reader readLine()String words[] = line split( )if(words[ ] equalsIgnoreCase( quit )) { System exit( )}else if(words[ ] equalsIgnoreCase( size ) &&words length >= ) { try { int size = Integer parseInt(words[ ])pool setPoolSize(size)}catch(Exception e) {
}
}else if(words[ ] equalsIgnoreCase( max ) &&words length >= ) { try { int max = Integer parseInt(words[ ])pool setMaxPoolSize(max)}catch(Exception e) {
}
}else if(words[ ] equalsIgnoreCase( task ) &&words length >= ) { try { int timelen = Integer parseInt(words[ ])SimpleTask task = new SimpleTask(words[ ] timelen * )pool processTask(task)}catch(Exception e) {
}
}
} catch (IOException e) { e printStackTrace()
}
}
}
}
cmdThread start()
/**//*
for(int i= i<i++){
SimpleTask task = new SimpleTask( Task + i (i+ )* )pool processTask(task)
}*/
}
}
class SimpleTask implements ThreadTask {
private String taskName
private int timeLen
public SimpleTask(String taskName int timeLen) { this taskName = taskNamethis timeLen = timeLen
}
public void run() { System out println(Thread currentThread() getId() +
: START TASK + taskName + )
try { Thread sleep(timeLen)} catch (InterruptedException e) {
}
System out println(Thread currentThread() getId() +
: END TASK + taskName + )
}
}
使用此线程池相当简单 下面两行代码初始化线程池
ThreadPool pool = new ThreadPool( )pool init()
要处理的任务实现ThreadTask 接口即可(如测试代码里的SimpleTask) 这个接口只有一个方法run()
两行代码即可调用
lishixinzhi/Article/program/Java/hx/201311/27203
java多线程开发时,常常用到线程池技术,这篇文章是对创建java线程池时的七个参数的详细解释。从源码中可以看出,线程池的构造函数有7个参数,分别是corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler。下面会对这7个参数一一解释。
线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会 被销毁,除非设置了allowCoreThreadTimeOut。这里的最小线程数量即是corePoolSize。
一个任务被提交到线程池后,首先会缓存到工作队列(后面会介绍)中,如果工作队列满了,则会创建一个新线程,然后从工作队列中的取出一个任务交由新线程来处理,而将刚提交的任务放入工作队列。线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize来指定。
一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁,这里的指定时间由keepAliveTime来设定。
keepAliveTime的计量单位
新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务。jdk中提供了四种工作队列:
基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。
基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,因此使用该工作队列时,参数maxPoolSize其实是不起作用的。
一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。
具有优先级的无界阻塞队列,优先级通过参数Comparator实现。
创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等
当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,该如何处理呢。这里的拒绝策略,就是解决这个问题的,jdk中提供了4中拒绝策略:
该策略下,在 调用者线程 中直接执行该被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。
该策略下,直接丢弃任务,并抛出RejectedExecutionException异常。
该策略下,直接丢弃任务,什么都不做。
该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列
到此,构造线程池时的七个参数,就全部介绍完毕了。
java创建线程的方式有三种\x0d\x0a第一种是继承Thread类 实现方法run() 不可以抛异常 无返回值\x0d\x0a第二种是实现Runnable接口 实现方法run() 不可以抛异常 无返回值\x0d\x0a第三种是实现Callable接口,接口中要覆盖的方法是 public call() 注意:此方法可以抛异常,而前两种不能 而且此方法可以有返回值\x0d\x0a\x0d\x0a第三种如何运行呢 Callable接口在util.concurrent包中,由线程池提交\x0d\x0aimport java.util.concurrent.*\x0d\x0aExecutorService e = Executors.newFixedThreadPool(10)参数表示最多可以运行几个线程\x0d\x0ae.submit()这个里面参数传 实现Callable接口那个类的对象