多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。
假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。
如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。
一个线程池包括以下四个基本组成部分:
1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。
线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。
线程池不仅调整T1,T3产生的时间段,而且它还显著减少了创建线程的数目
线程池管理器以及工作线程
package com.thread;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
public class DefaultThreadPool<Job extends Runnable> {
// 线程池维护工作者线程的最大数量
private static final int MAX_WORKER_NUMBERS = 10;
// 线程池维护工作者线程的默认值
private static final int DEFAULT_WORKER_NUMBERS = 5;
// 线程池维护工作者线程的最小数量
private static final int MIN_WORKER_NUMBERS = 1;
// 维护一个工作列表,里面加入客户端发起的工作
private final LinkedList<Job> jobs = new LinkedList<Job>();
// 工作者线程的列表
private final List<Worker> workers = Collections
.synchronizedList(new ArrayList<Worker>());
// 工作者线程的数量
private int workerNum;
// 每个工作者线程编号生成
private AtomicLong threadNum = new AtomicLong();
// 生成线程池
public DefaultThreadPool() {
this.workerNum = DEFAULT_WORKER_NUMBERS;
initializeWorkers(this.workerNum);
}
public DefaultThreadPool(int num) {
if (num < MIN_WORKER_NUMBERS) {
this.workerNum = DEFAULT_WORKER_NUMBERS;
} else {
this.workerNum = num;
}
initializeWorkers(this.workerNum);
}
// 初始化每个工作者线程
private void initializeWorkers(int num) {
for (int i = 0; i < num; i++) {
Worker worker = new Worker("编号"+i + ":");
// 添加到工作者线程的列表
workers.add(worker);
// 启动工作者线程
Thread thread = new Thread(worker);
thread.start();
}
}
public void execute(Job job) {
if (job != null) {
// 根据线程的"等待/通知机制"这里必须对jobs加锁
synchronized (jobs) {
jobs.addLast(job);
jobs.notify();
}
}
}
// 关闭线程池即关闭每个工作者线程
public void shutdown() {
for (Worker w : workers) {
w.shutdown();
}
}
// 增加工作者线程
public void addWorkers(int num) {
// 加锁,防止该线程还么增加完成而下个线程继续增加导致工作者线程超过最大值
synchronized (jobs) {
if (num + this.workerNum > MAX_WORKER_NUMBERS) {
num = MAX_WORKER_NUMBERS - this.workerNum;
}
initializeWorkers(num);
this.workerNum += num;
}
}
// 减少工作者线程
public void removeWorker(int num) {
synchronized (jobs) {
if (num >= this.workerNum) {
throw new IllegalArgumentException("超过了已有的线程数量");
}
for (int i = 0; i < num; i++) {
Worker worker = workers.get(i);
if (worker != null) {
// 关闭该线程并从列表中移除
worker.shutdown();
workers.remove(i);
}
}
this.workerNum -= num;
}
}
public int getJobSize() {
return workers.size();
}
// 定义工作者线程
class Worker implements Runnable {
// 表示是否运行该worker
private volatile boolean running = true;
private String name;
public Worker(String name) {
this.name = name;
}
public void run() {
System.out.println(name + "线程初始化");
while (running) {
Job job = null;
// 线程的等待/通知机制
synchronized (jobs) {
if (jobs.isEmpty()) {
try {
System.out.println(name + "jobs wait....");
jobs.wait();// 线程等待唤醒
} catch (InterruptedException e) {
// 感知到外部对该线程的中断操作,返回
Thread.currentThread().interrupt();
return;
}
}
if(!jobs.isEmpty()){
// 取出一个job
job = jobs.removeFirst();
}
}
// 执行job
if (job != null) {
System.err.println(name + "线程执行操作");
job.run();
}
}
}
// 终止该线程
public void shutdown() {
running = false;
}
}
}
实现线程的任务类
package com.thread;
public class RunableTest implements Runnable {
private String name;
public RunableTest(String name){
this.name = name;
}
public void run() {
System.out.println("RunableTest:"+name);
}
}
测试类
package com.thread;
public class MyThread{
public static void main(String args[]) throws Exception{
DefaultThreadPool<Runnable> dp = new DefaultThreadPool<Runnable>(10);
dp.execute(new RunableTest("AA"));
dp.execute(new RunableTest("BB"));
dp.execute(new RunableTest("CC"));
dp.execute(new RunableTest("DD"));
dp.execute(new RunableTest("EE"));
dp.execute(new RunableTest("FF"));
dp.execute(new RunableTest("GG"));
dp.execute(new RunableTest("HH"));
}
}
测试结果
编号10:线程初始化
编号11:线程初始化
编号12:线程初始化
编号15:线程初始化
编号13:线程初始化
编号10:jobs wait....
编号15:jobs wait....
编号16:线程初始化
编号16:jobs wait....
编号17:线程初始化
编号12:jobs wait....
编号11:jobs wait....
编号14:线程初始化
编号19:线程初始化
编号17:jobs wait....
编号13:jobs wait....
编号19:jobs wait....
编号18:线程初始化
编号18:jobs wait....
编号14:jobs wait....
编号10:线程执行操作
RunableTest:AA
编号10:线程执行操作
编号19:线程执行操作
RunableTest:CC
编号19:线程执行操作
RunableTest:BB
编号16:jobs wait....
编号15:jobs wait....
编号12:线程执行操作
RunableTest:HH
编号11:线程执行操作
RunableTest:GG
RunableTest:EE
编号17:线程执行操作
RunableTest:FF
编号13:线程执行操作
RunableTest:DD
编号10:jobs wait....
编号13:jobs wait....
编号17:jobs wait....
编号19:jobs wait....
编号11:jobs wait....
编号12:jobs wait....