在一篇文章中:工作线程模式,未考虑如下情况:
1.任务里很大时,工作线程不足时,导致客户端提交任务将阻塞的情况
2.任务里很少时,应该回收池中空闲的线程数量,回收资源
1.线程池类:
package threadpool;
import java.util.LinkedList;
import java.util.Vector;
/**
* 负责接收和存储任务,以及工作线程生命周期,主要职责如下:
* 1.submit接口,提供给客户端 ,客户端 通过此接口提交任务
* 到线程池
*
* 2.shutdowm接口,关闭本池并释放池中资源
* @author lxb
*
*/
public class ThreadPool {
private final LinkedList<TaskRequest> requestQueue; // 保存的请求队列
private int count; // 请求队列中的请求数量
private final LinkedList<WorkerThread> threadPool; // 工人线程池
public ThreadPool(int threads) {
this.requestQueue = new LinkedList<TaskRequest>();
this.count = 0;
threadPool = new LinkedList<WorkerThread>();
for (int i = 0; i < threads; i++) {
threadPool.addLast(new WorkerThread("Worker-" + i, this));
}
}
/**
* 当任务量很大时,添加工作线程
* @param thread
*/
public void addWorkers(WorkerThread thread){
threadPool.addLast(thread);
thread.start();
}
/**
* 当工作量很少时删除工作线程,节省开支
* @param count
*/
public void deleteWorkers(int count){
if(count > threadPool.size()){ //这里不取=保证池中始终有一个线程在工作
for(int i=0;i<count;i++){
threadPool.pop();
}
}
}
/**
* 开启工作线程
*/
public void startWorkers() {
for (int i = 0; i < threadPool.size(); i++) {
threadPool.get(i).start();
}
}
public void stopAllWorkers(){
for(int i=0;i<threadPool.size();i++){
threadPool.get(i).stopThread();
}
}
/**
* 保存客户端发来的工作请求
*
* @param request
* @throws InterruptedException
*/
public synchronized void putRequest(TaskRequest request) throws InterruptedException {
// 当Request的数量大于或等于同时接受的数目时候,要等待
while (!requestQueue.isEmpty()&&count >= requestQueue.size() ) {
wait();
}
requestQueue.addLast(request);
count++;
notifyAll();
}
public synchronized TaskRequest takeRequest() throws InterruptedException {
while (count <= 0) {
wait();
}
TaskRequest request = requestQueue.pop();
count--;
notifyAll();
return request;
}
}
package threadpool;
/**
* 工作线程,处理客户端发来的具体的工作请求
* @author lxb
*
*/
public class WorkerThread extends Thread{
private final ThreadPool threadPool;
private volatile boolean terminated = false; //停止请求标志
public WorkerThread(String name,ThreadPool threadPool){
super(name);
this.threadPool = threadPool;
}
public void run() {
try {
while (!terminated) {
try {
TaskRequest request = threadPool.takeRequest();
request.execute();
} catch (InterruptedException e) {
terminated = true;
}
}
} finally {
System.out.println(Thread.currentThread().getName() + " is terminated.");
}
}
public void stopThread() {
terminated = true;
interrupt();
}
}
3.工作请求类:
package threadpool;
import java.util.Random;
/**
* 任务请求实体
* @author lxb
*
*/
public class TaskRequest {
private final String name;
private final int number;
private static final Random random = new Random();
public TaskRequest(String name, int number) {
this.name = name;
this.number = number;
}
public void execute() {
System.out.println(Thread.currentThread().getName() + " executes " + this);
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
}
}
public String toString() {
return "[ Request from " + name + " No." + number + " ]";
}
}
package threadpool;
import java.util.Random;
/**
* 不停的发送请求给工人类
*
* 1.创建请求实例,并将实例发送给管理工人线程的类
*
* @author lxb
*
*/
public class ClientThread extends Thread {
private final ThreadPool channel;
private static final Random random = new Random();
private volatile boolean terminated = false; // 停止请求标志
public ClientThread(String name, ThreadPool channel) {
super(name);
this.channel = channel;
}
public void run() {
try {
for (int i = 0; !terminated; i++) {
try {
TaskRequest request = new TaskRequest(getName(), i);
channel.putRequest(request);
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
terminated = true;
}
}
} finally {
System.out.println(Thread.currentThread().getName()
+ " is terminated.");
}
}
public void stopThread() {
terminated = true;
interrupt();
}
}
6.测试类:
package threadpool;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
ThreadPool channel = new ThreadPool(5); // Worker Thread数量
channel.startWorkers();
ClientThread alice = new ClientThread("Alice", channel);
ClientThread bobby = new ClientThread("Bobby", channel);
ClientThread chris = new ClientThread("Chris", channel);
alice.start();
bobby.start();
chris.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
alice.stopThread();
bobby.stopThread();
chris.stopThread();
channel.stopAllWorkers();
}
}