1.固定大小的线程池简介
线程池就是在程序启动的时候先建立几个可以使用的线程放在那里,然后等着具体的任务放进去,这个任务基本可以说都是Runnable的实现类,因此它减小了系统每次新建和销毁线程的开销,但同时增加了维护这些线程的开销,个中取舍看具体情况而定。固定大小的线程池就是在启动的时候创建了固定个数的线程放在那里等待使用。
2.包装一个线程池对象
public class TaskPool{
private final ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(9); // 创建一个大小为9的固定线程池,可以按照CPU的核数初步判定,如果CPU密集性任务则创建N+1个,如果是IO密集型任务则创建2N+1个,其中N即CPU的核数
protected void shutdown(){
// do something
// 这个方法等待线程池中所有已提交任务执行结束,不接收新任务,然后结束
executor.shutdown();
// 这个强制结束所有任务,然后正在等在的任务列表
// executor.shutdownNow();
}
protected void execute(Runnable command){
// do something
// 提交任务
executor.execute(command);
}
public void status(){
StringBuffer sb = new StringBuffer();
// 当前正在执行任务的线程数
sb.append(executor.getActiveCount() + "\n");
// 当前正在等待执行的线程数
sb.append(executor.getQueue().size() + "\n");
// 返回已经完成的线程数
sb.append(executor.getCompletedTaskCount() + "\n");
System.out.println(sb.toString());
// 注:以上方法都是返回一个大概值,因为线程在执行中,这些状态随时都会改变
}
}
3.使用线程池
public class Launcher{
private TaskPool taskPool = new TaskPool();
public static void main(String[] args){
// 新建100个任务,Runnable的实现类Task
Task[] tasks = new Task[100];
for (int i = 0; i < tasks.length; i++){
tasks[i] = new Task("Task " + (i+1));
// 提交到线程池运行
taskPool.execute(task[i]);
if ( i % 50 == 0){
taskPool.status();
}
}
private static class Task implements Runnable{
private String name;
public Task(String name){
this.name = name;
}
public void run(){
// do something
System.out.println("我的名字是:" + this.name);
}
}
}