構(gòu)成線程池的基本元素
- 線程池中的線程
- 任務(wù)隊(duì)列
- 生產(chǎn)者
- 消費(fèi)者
- 線程池
public class ThreadPool {
//用blockingQueue創(chuàng)建一個任務(wù)隊(duì)列,初始化長度為5
private BlockingQueue<Runnable> tasksQueue = new ArrayBlockingQueue<Runnable>(5);
//定義線程池中消費(fèi)者最大數(shù)量
private int consumers = 3;
//這個方法提供給所有的任務(wù)生產(chǎn)者卜壕,產(chǎn)生新的任務(wù)插入
public void insertTask(Runnable task) throws InterruptedException{
tasksQueue.put(task);
}
//線程池的初始化
public ThreadPool(){
//激活消費(fèi)者,等待問題到來
for(int i=1;i<=consumers;i++){
Solver consumer = new Solver(tasksQueue,i);
consumer.start();
}
}
}
- 消費(fèi)者
public class Solver extends Thread{
//引用線程池的任務(wù)隊(duì)列烙常,消費(fèi)者不斷的從里面取得任務(wù)去解決
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){
//從隊(duì)列中取出任務(wù)執(zhí)行轴捎,注意這里用了take方法,所以如果隊(duì)列空了,那么線程會等待侦副,直到有任務(wù)來了侦锯,繼續(xù)執(zhí)行
Runnable task = taskQueue.take();
System.out.println("消費(fèi)者"+name+"接收了一個任務(wù)");
task.run();
System.out.println("消費(fèi)者"+name+"解決了一個任務(wù)");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 生產(chǎn)者
public class ProblemCreater {
public static void main(String[] args) throws Exception {
//初始化線程池
ThreadPool threadPool = new ThreadPool();
//生成者不斷產(chǎn)生任務(wù)
for(int i=1;i<10;i++){
//定義一個新的任務(wù)
Runnable task = new Runnable(){
public void run(){
Random random = new Random();
//隨機(jī)一個數(shù)字模擬需要解決的時間
int randomTime = Math.abs(random.nextInt())%20;
//System.out.println("這個任務(wù)需要解決時間為:"+randomTime);
try {
Thread.sleep(randomTime*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//將問題插入到線程池任務(wù)隊(duì)列中
threadPool.insertTask(task);
System.out.println("插入新的任務(wù)"+i);
}
}
}
問題
- 任務(wù)隊(duì)列的大小:如果消費(fèi)者的消費(fèi)能力跟不上生產(chǎn)者的秦驯,這個任務(wù)隊(duì)列的長度就會越來越長尺碰。
- 線程池中線程的個數(shù):線程池中能同時運(yùn)行的最多的線程數(shù),如果線程數(shù)太多的話會嚴(yán)重影響系統(tǒng)的穩(wěn)定性汇竭。