JAVA的Executors源码:(可以看出底层都是通过ThreadPoolExecutor来具体设置的~)
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public static ExecutorService newFixedThreadPool(int nThreads){
returnnewThreadPoolExecutor(nThreads, nThreads,
0L,TimeUnit.MILLISECONDS,
newLinkedBlockingQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory){
returnnewFinalizableDelegatedExecutorService
(newThreadPoolExecutor(1,1,
0L,TimeUnit.MILLISECONDS,
newLinkedBlockingQueue<Runnable>(),
threadFactory));
}
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize){
returnnewScheduledThreadPoolExecutor(corePoolSize);
}
(
ScheduledThreadPoolExecutor :
extends ThreadPoolExecutor ,
implements ScheduledExecutorService
)
ThreadPoolExecutor自定义
以上是一些JAVA封装现成设置后得到的线程池,更灵活的自定义设置:
ThreadPoolExecutor:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
ThreadPoolExecutor
(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit
unit,
BlockingQueue
<
Runnable
> workQueue,
ThreadFactory
threadFactory,
RejectedExecutionHandler
handler)
RejectedExecutionHandler:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/RejectedExecutionHandler.html
ThreadPoolExecutor提供了一系列参数来配置线程池,通过不同的参数可以创建不同的线程池:
1.
2.
3.
4.
5.
6.
7.
corePoolSize
:核心线程数,默认情况下,核心线程会在线程中一直存活;
2.
maximumPoolSize
:最大线程数,当活动线程数达到这个数值后,后续的任务将会被阻塞;
3.
keepAliveTime
:非核心线程闲置时的超时时长,超过这个时长,闲置的非核心线程就会被回收;
4.
unit
:用于指定keepAliveTime参数的时间单位,有
TimeUnit.MILLISECONDS
、
TimeUnit.SECONDS
、
TimeUnit.MINUTES
等;
5.
workQueue
:任务队列,通过线程池的execute方法提交的Runnable对象会存储在这个参数中;
6.
threadFactory
:线程工厂,为线程池提供创建新线程的功能。它是一个接口,它只有一个方法
Thread newThread(Runnable r)
;
7.
RejectedExecutionHandler
:当线程池无法执行新任务时,可能是由于任务队列已满或者是无法成功执行任务,这个时候就会调用这个
Handler的
rejectedExecution
方法来通知调用者,默认情况下,
rejectedExecution
会直接抛出个
rejectedExecutionException
。
ThreadPoolExecutor执行任务的规则:
1.如果线程池中的线程数未达到核心线程的数量,那么会直接启动一个核心线程来执行任务;
2.如果线程池中的线程数量已经达到或者超过核心线程的数量,那么任务会被插入到任务队列中排队等待执行;
3.如果在步骤2中无法将任务插入到的任务队列中,可能是任务队列已满,这个时候如果线程数量没有达到规定的最大值,那么会立刻启动非核心线程来执行这个任务;
4.如果步骤3中线程数量已经达到线程池规定的最大值,那么就拒绝执行此任务,ThreadPoolExecutor会调用
1.如果线程池中的线程数未达到核心线程的数量,那么会直接启动一个核心线程来执行任务;
2.如果线程池中的线程数量已经达到或者超过核心线程的数量,那么任务会被插入到任务队列中排队等待执行;
3.如果在步骤2中无法将任务插入到的任务队列中,可能是任务队列已满,这个时候如果线程数量没有达到规定的最大值,那么会立刻启动非核心线程来执行这个任务;
4.如果步骤3中线程数量已经达到线程池规定的最大值,那么就拒绝执行此任务,ThreadPoolExecutor会调用
RejectedExecutionHandler
的
rejectedExecution
方法来通知调用者。
使用示例:
自定义线程池工厂类:
public final class ThreadUtils {
private static final String TAG = ThreadUtils.class.getSimpleName();
//线程池为无限大,复用线程,灵活回收空闲线程
// name:线程名字
public static ThreadPoolExecutor newCachedThreadPool(final String name) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
new CounterThreadFactory(name),
new LogDiscardPolicy());
}
//定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
//name:线程名字, nThread:线程数
public static ThreadPoolExecutor newFixedThreadPool(final String name, int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
new CounterThreadFactory(name),
new LogDiscardPolicy());
}
//创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
//name:线程名字
public static ThreadPoolExecutor newSingleThreadExecutor(final String name) {
return newFixedThreadPool(name, 1);
}
//创建一个定长线程池,支持定时及周期性任务执行。
/*使用:
scheduledThreadPool.schedule(new Runnable() {
@Override
public void run() {
System.out.println("delay 3 seconds");
}
}, 3, TimeUnit.SECONDS); //表示延迟3秒执行。
*/
public static ScheduledExecutorService newScheduledExecutorService(int nThreads){
return Executors.newScheduledThreadPool(nThreads);
}
public static class LogDiscardPolicy implements RejectedExecutionHandler {
public LogDiscardPolicy() {
}
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
LogUtils.v(TAG, "rejectedExecution() " + r + " is discard.");
}
}
public static class CounterThreadFactory implements ThreadFactory {
private int count;
private String name;
public CounterThreadFactory(String name) {
this.name = (name == null ? "Android" : name);
}
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setName(name + "-thread #" + count++);
return thread;
}
}
}