构成线程池的基本元素
- 线程池
public class ThreadPool {
//用blockingQueue创建一个任务队列,初始化长度为5
private BlockingQueue<Runnable> tasksQueue = new ArrayBlockingQueue<Runnable>(5);
//定义线程池中消费者最大数量
private int consumers = 3;
//这个方法提供给所有的任务生产者,产生新的任务插入
public void insertTask(Runnable task) throws InterruptedException{
tasksQueue.put(task);
}
//线程池的初始化
public ThreadPool(){
//激活消费者,等待问题到来
for(int i=1;i<=consumers;i++){
Solver consumer = new Solver(tasksQueue,i);
consumer.start();
}
}
}
- 消费者
public class Solver extends Thread{
//引用线程池的任务队列,消费者不断的从里面取得任务去解决
private BlockingQueue<Runnable> taskQueue = null;
private String name;
Solver(BlockingQueue<Runnable> tasks,int name){
this.taskQueue = tasks;
this.name = String.valueOf(name);
}
public void run(){
try {
while(true){
//从队列中取出任务执行,注意这里用了take方法,所以如果队列空了,那么线程会等待,直到有任务来了,继续执行
Runnable task = taskQueue.take();
System.out.println("消费者"+name+"接收了一个任务");
task.run();
System.out.println("消费者"+name+"解决了一个任务");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 生产者
public class ProblemCreater {
public static void main(String[] args) throws Exception {
//初始化线程池
ThreadPool threadPool = new ThreadPool();
//生成者不断产生任务
for(int i=1;i<10;i++){
//定义一个新的任务
Runnable task = new Runnable(){
public void run(){
Random random = new Random();
//随机一个数字模拟需要解决的时间
int randomTime = Math.abs(random.nextInt())%20;
//System.out.println("这个任务需要解决时间为:"+randomTime);
try {
Thread.sleep(randomTime*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//将问题插入到线程池任务队列中
threadPool.insertTask(task);
System.out.println("插入新的任务"+i);
}
}
}
问题
- 任务队列的大小:如果消费者的消费能力跟不上生产者的,这个任务队列的长度就会越来越长。
- 线程池中线程的个数:线程池中能同时运行的最多的线程数,如果线程数太多的话会严重影响系统的稳定性。