import java.util.LinkedList; |
/** |
* 线程池,继承ThreadGroup。 ThreadGroup用于处理一组线程的类,它是一种树状结构,他的下层节点还可以是ThreadGroup对象 |
*/ |
public class MyThreadPool extends ThreadGroup { |
/** 标志线程池是否开启 */ |
private boolean isAlive; |
/** 线程池中的任务队列 */ |
private LinkedList taskQueue; |
/** 线程池中的线程ID */ |
private int threadID; |
/** 线程池ID */ |
private static int threadPoolID; |
/** |
* 创建新的线程池,numThreads是池中的线程数 |
*/ |
public MyThreadPool( int numThreads) { |
super ( "ThreadPool-" + (threadPoolID++)); |
// 设置为该线程池是的daemon属性为true, |
// 表示当该线程池中所有线程都被销毁时,该线程池会自动被销毁 |
super .setDaemon( true ); |
this .isAlive = true ; |
// 新建一个任务队列 |
this .taskQueue = new LinkedList(); |
// 启动numThreads个工作线程 |
for ( int i = 0 ; i < numThreads; i++) { |
new PooledThread().start(); |
} |
} |
/** |
* 添加新任务 |
*/ |
public synchronized void performTask(Task task) { |
if (! this .isAlive) { |
// 线程被关则抛出IllegalStateException异常 |
throw new IllegalStateException(); |
} |
if (task != null ) { |
// 将任务放到任务队列的尾部 |
this .taskQueue.add(task); |
// 通知工作线程取任务 |
notify(); |
} |
} |
/** |
* 获取任务 |
*/ |
protected synchronized Task getTask() throws InterruptedException { |
// 如果任务列表为空,而且线程池没有被关闭,则继续等待任务 |
while ( this .taskQueue.size() == 0 ) { |
if (! this .isAlive) { |
return null ; |
} |
wait(); |
} |
// 取任务列表的第一个任务 |
return (Task) this .taskQueue.removeFirst(); |
} |
/** |
* 关闭线程池,所有线程停止,不再执行任务 |
*/ |
public synchronized void close() { |
if (isAlive) { |
this .isAlive = false ; |
// 清除任务 |
this .taskQueue.clear(); |
// 中止线程池中所有线程 |
this .interrupt(); |
} |
} |
/** |
* 关闭线程池,并等待线程池中的所有任务被运行完。 但是不能接受新的任务。 |
*/ |
public void join() { |
// 通知其他等待线程“该线程池已关闭”的消息 |
synchronized ( this ) { |
isAlive = false ; |
notifyAll(); |
} |
// 等待所有线程完成 |
// 首先建立一个新的线程数组。activeCount方法获取线程池中活动线程的估计数 |
Thread[] threads = new Thread[ this .activeCount()]; |
// 将线程池中的活动线程拷贝到新创建的线程数组threads中。 |
int count = this .enumerate(threads); |
for ( int i = 0 ; i < count; i++) { |
try { |
// 等待线程运行结束 |
threads[i].join(); |
} catch (InterruptedException ex) { |
} |
} |
} |
/** |
* 内部类,用于执行任务的工作线程 |
*/ |
private class PooledThread extends Thread { |
// 构造方法 |
public PooledThread() { |
// 第一个参数为该线程所在的线程组对象,即当前线程池对象 |
// 第二个参数为线程名字 |
super (MyThreadPool. this , "PooledThread-" + (threadID++)); |
} |
public void run() { |
// 如果该线程没有被中止 |
while (!isInterrupted()) { |
// 获取任务 |
Task task = null ; |
try { |
task = getTask(); |
} catch (InterruptedException ex) { |
} |
// 只要线程池的任务列表不为空,getTask方法总能得到一个任务。 |
// 若getTask()返回null,则表示线程池中已经没有任务,而且线程池已被关闭。 |
if (task == null ) { |
return ; |
} |
// 运行任务,吸收异常 |
try { |
task.perform(); |
} catch (Throwable t) { |
// 当线程组中的线程有未被捕获的异常发生时,JVM就会去调用uncaughtException方法。 |
uncaughtException( this , t); |
} |
} |
} |
} |
} |
初级程序员
by: 淡定 发表于:2017-08-14 21:25:36 顶(0) | 踩(0) 回复
沙发
回复评论