Java 常用的线程池
Executors
Java的Executors提供了四种线程池分别是
1、newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。(线程最大并发数不可控制)
2、newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3、newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。
4、newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
newFixedThreadPool 创建一个定长线程池
Executors.newFixedThreadPool(10);//定长的参数的线程池,如果超过则等待
ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10);//固定长度
for (int i = 0; i < 100; i++) {
newFixedThreadPool.execute(new Runnable() {
public void run() {
String name = Thread.currentThread().getName();//得到当前线程名称
System.out.println(name);
}
});
}
Executors.newCachedThreadPool();//可缓存的线程池,最大线程根据任务来决定,线程次数不可控制
ExecutorService newFixedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 100; i++) {
newFixedThreadPool.execute(new Runnable() {
public void run() {
String name = Thread.currentThread().getName();//得到当前线程名称
System.out.println(name);
}
});
}
newScheduledThreadPool 创建一个定时任务的线程池
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);//当中的参数其实并无意义
service.scheduleAtFixedRate(
new Runnable() {
public void run() {
System.out.println("神仙操作" + new Date());
}
}, 1,3, TimeUnit.SECONDS);
//其中的四个参数分别表示
//task 线程任务
//1 表示 在这个线程池首次创建之后延迟一秒执行
//3 表示 在首次执行之后每次隔多久执行一次
//TimeUtil.SECONDS//表示秒
//TimeUnit.MINUTES;//表示分钟
//TimeUnit.HOURS;//表示小时
//TimeUnit.DAYS;//表示天
}
newSingleThreadExecutor 创建一个单线程化的线程池
ExecutorService newFixedThreadPool = Executors.newSingleThreadExecutor();
for (int i = 0; i < 100; i++) {
newFixedThreadPool.execute(new Runnable() {
public void run() {
String name = Thread.currentThread().getName();//得到当前线程名称
System.out.println(name);
}
});
}
ThreadPoolExecutor
Java.util.concurrent.ThreadPoolExecutor类是ExecutorSerivce接口的具体实现。ThreadPoolExecutor使用线程池中的一个线程来执行给定的任务(Runnable或者Callable)
可自定义线程池
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
//差距在线程的工厂
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
- corePoolSize:所谓的核心线程数,可以大致理解为长期驻留的线程数目(除非设置了
allowCoreThreadTimeOut)。对于不同的线程池,这个值可能会有很大区别,比如 newFixedThreadPool会将其设置为 nThreads,而对于 newCachedThreadPool 则是为 0。 - maximumPoolSize:顾名思义,就是线程不够时能够创建的最大线程数。同样进行对比,对于
newFixedThreadPool,当然就是 nThreads,因为其要求是固定大小,而 newCachedThreadPool 则是Integer.MAX_VALUE。 - keepAliveTime:空闲线程的保活时间,如果线程的空闲时间超过这个值,那么将会被关闭。注意此值生效条件必须满足:空闲时间超过这个值,并且线程池中的线程数少于等于核心线程数。
- TimeUnit:时间单位。
- BlockingQueue:任务丢列,用于存储线程池的待执行任务的。
- ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原 则对元素进行排序。
- LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。
- SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法 Executors.newCachedThreadPool使用了这个队列。
- PriorityBlockingQueue:一个具有优先级的无限阻塞队列。
- threadFactory:用于生成线程,一般我们可以用默认的就可以了。
- handler:当线程池已经满了,但是又有新的任务提交的时候,该采取什么策略由这个来指定。有几种方式可供选择,像抛出异常、直接拒绝然后返回等,也可以自己实现相应的接口实现自己的逻辑。
//默认使用AbortPolicy()//直接抛出异常
private static final RejectedExecutionHandler defaultHandler =
new AbortPolicy();
- AbortPolicy:直接抛出异常。
- CallerRunsPolicy:只用调用者所在线程来运行任务。
- DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。
- DiscardPolicy:不处理,丢弃掉。
当然也可以根据应用场景需要来实现RejectedExecutionHandler接口自定义策略。如记录日志或持久化不能处理的任务。