线程池:涉及到池的概念,肯定是为了重复利用资源,避免资源的重复创建,以及方便统一管理,线程池也不例外,可以避免频繁的创建线程和销毁线程带来的性能消耗,也可以对线程的并发数以及行为等进行一个统一的管理。
java中有一个Executor接口,它就是线程池的顶层接口,而真正的实现是ThreadPoolExecutor。
ThreadPoolExecutor的使用:
public class ExecutorText {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize, //核心线程数
maximumPoolSize, //最大线程数
keepAliveTime, //线程超时时间
unit, //超时时间单位
workQueue, //阻塞队列
threadFactory //线程创建工厂
);
}
}
这是我们完全自定义一个自己的线程池,参数详解:
corePoolSize : 核心线程数,默认情况下会在线程池中一直存活,即使处于闲置状态。如果将executor.allowCoreThreadTimeOut(true) ,则会根据keepAliveTime进行超时终止。
maximumPoolSize :最大线程数,除了核心线程还可以创建一些非核心线程来帮忙处理任务,不过处理完之后便会根据keepAliveTime消亡。maximumPoolSize必须大于等于corePoolSize,否则抛出异常 throw new IllegalArgumentException();
keepAliveTime ,unit: 超时时间,与时间的单位。非核心线程会根据这个闲置时间来销毁,如果设置了allowCorThreadTimeOut,那么对于核心线程也会起效。
workQueue : 阻塞队列,保存Runnable对象的
threadFactory : 为创建新Thread的接口。
使用:
public class ExecutorText {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
1, //核心线程数
1, //最大线程数
1, //线程超时时间
TimeUnit.MILLISECONDS, //超时时间单位
new LinkedBlockingDeque(1), //阻塞队列
new ThreadFactory() {
public Thread newThread(Runnable r) {
return new Thread(r);
}
} //线程创建工厂
);
executor.submit(new Runnable() {
public void run() {
System.out.println("fuck.." + Thread.currentThread().getName());
}
});
}
}
由于线程池没有设置allowCoreThreadTimeOut,所以核心线程不会超时挂掉,所以不会销毁,如果确定使用完了,请手动调用停止线程池。
//安全的执行完所有任务停止,并且不能再添加任务执行
executor.shutdown();
//立即停止,并返回一个List存储的是尚未执行的人物。
executor.shutdownNow();