关键词
吞吐量、资源利用率、大量同类型的任务、线程池、工作线程、任务队列
应用场景
- 最佳资源利用率
- 程序吞哇量
- 任务明确但数量多
- thread创建和管理的成本
- 合理构建程序结构,封装对同一类型事物的处理
这是有风险的
- 资源都被池给占用了
- 工作线程并发错误
- 工作线程异常产生泄漏
- 工作线程时限
- 被大量的请求压垮
主动权在你,你会考虑?
- 考虑和避免任务间的并发问题
- 考虑工作线程加上时限处理逻辑
- 考虑合理的线程池大小
- 考虑合理的队列大小
- 考虑CPU是几个核
- 对客户要执行任务进行归类
- 这不是一个池子,这可以是多个
- 考虑线程所控制的资源
- 自身资源
- 所管理的资源
- JDBC
- 套接字
- 文件
- 哪块耗时多?
- 是创建和管理线程生命周期的时间
- 还是真实任务处理时间
线程池基本结构
- 任务队列
- 工作线程集合
- 队列和集合的管理逻辑
- 控制队列的大小
- 控制工作线程集合的大小
- 管理工作线程生命周期
- 控制工作线程执行任务
- 任务逻辑异常
- 任务耗时问题
- 任务并发引用
- 避免错误
- 死锁
- 资源过载
- 并发问题
线程池基础
/**
* 线程池基础
* @author WangYanCheng
* @version 2012-11-31
*/
public class ThreadPool_01 {
// 有一个任务队列
private final LinkedList<Runnable> queue;
// 有一个工作线程数量
private final int workerThreadNums;
// 有一个工作线程集合
private final ThreadWorker[] threadWorkers;
// 实际工作线程数量
private int thNums;
/**
* Constructor
* @param workerThreadNums 初始工作线程数量
*/
public ThreadPool_01(int workerThreadNums) {
this.queue = new LinkedList<Runnable>();
this.workerThreadNums = workerThreadNums;
this.threadWorkers = new ThreadWorker[this.workerThreadNums];
for (ThreadWorker tw : this.threadWorkers) {
tw = new ThreadWorker(ThreadWorker.THNAMEPREFIX.concat(String.valueOf(thNums++)));
tw.start();
}
}
/**
* 提供给客户端的API,负责接收逻辑任务,并调度执行
* @param r 可执行任务
*/
public void execute(Runnable r) {
synchronized (queue) {
queue.add(r);
// 不存在共享资源的模式,只通知一个等待线程即可
queue.notify();
}
}
/**
* 线程池中的工作线程,其生命周期被池对象完全控制,负责执行任务
* @author WangYanCheng
* @version 2012-11-31
*/
private class ThreadWorker extends Thread {
private static final String THNAMEPREFIX = "TW_";
/**
* Constructor
* @param thName
*/
public ThreadWorker(String thName) {
super(thName);
}
@Override
public void run() {
Runnable run;
while (true) {
synchronized (queue) {
while (queue.isEmpty()) {
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
run = queue.removeFirst();
}
// 任务逻辑处理异常一定不要影响到基础线程
try {
run.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* 充当客户端,负责构造可执行的任务
* @author WangYanCheng
* @version 2012-11-31
*/
private class ThreadTester extends Thread {
public ThreadTester() {
super();
setName("ThreadTester");
start();
}
@Override
public void run() {
int taskCount = 1;
while (true) {
execute(new VirtualTask(VirtualTask.TASKPREFIX.concat(String.valueOf(taskCount++))));
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 任务实例
* @author WangYanCheng
* @version 2012-11-31
*/
private class VirtualTask implements Runnable {
private static final String TASKPREFIX = "CT_";
/** 任务Id */
private String taskId;
/**
* Constructor
* @param taskId 任务Id
*/
public VirtualTask(String taskId) {
this.taskId = taskId;
}
/**
* 任务逻辑入口
*/
public void run() {
System.out.println(this);
try {
Thread.sleep((long)(Math.random() * 5000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "VirtualTask [taskId=" + taskId + "]";
}
}
/**
* 测试入口
* @param args 参数列表
*/
public static void main(String[] args) {
ThreadPool_01 tp01 = new ThreadPool_01(2);
tp01.new ThreadTester();
}
}
图
资料
- Java Thread 3th
- http://www.ibm.com/developerworks/cn/java/j-jtp0730/
后续
- Java#Thread Pool支持