十四,线程池详解
之前我们已经了解ExecutorService接口声明的方法:
public abstract T invokeAny(Collection extends Callable>) throws InterruptedException,ExecutionException
public abstract T invokeAny(Collection extends Callable>,long,TimeUnit) throws InterruptedException,ExecutionException,TimeoutException
public abstract List> invokeAll(Collection extends Callable>) throws InterruptedException
public abstract List> invokeAll(Collection extends Callable>,long,TimeUnit) throws InterruptedException
public abstract Future submit(Runnable,T)
public abstract Future submit(Callable)
public abstract boolean awaitTermination(long,TimeUnit) throws InterruptedException
public abstract boolean isShutdown()
public abstract boolean isTerminated()
public abstract List shutdownNow()
public abstract Future> submit(Runnable)
public abstract void execute(Runnable) 继承自Executor这个顶级接口
public abstract void shutdown()
API线程池使用示例
使用线程池要自己设置参数,做到每个参数心中有数。
下面具体举个线程池的例子,这也是API中Executors.newCachedThreadPool();的实现
public class ThreadPoolTool {
public static final ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
0,
Integer.MAX_VALUE,
60L,
TimeUnit.SECONDS,
new SynchronousQueue());
public static void execute(Runnable command){
THREAD_POOL_EXECUTOR.execute(command);
}
}
线程池几个参数的说明
参数名
说明
corePoolSize
核心线程数,一直存活,当小于核心线程数的时候优先创建(只有在工作队列满的情况下才会创建超出这个数量的线程)
maximumPoolSize
线程池允许的最大线程数,当大于核心线程数且队列满,创建直到这个数
keepAliveTime
空闲线程超时间,当线程数多于核心线程数时,空闲的线程会在这个时间退出,直到线程数等于核心线程数
BlockingQueue workQueue
阻塞队列,如果是ArrayBlockingQueue可以限制队列大小
BlockingQueue是个接口,有几个很重要的子类
下面的表格要熟
Summary of BlockingQueue methods
Throws exception
Special value
Blocks
Times out
Insert
add(e)
offer(e)
put(e)
Remove
remove()
poll()
take()
Examine
element()
peek()
not applicable
它有这么几个常用和不常用子类
子类名
说明
LinkedBlockingQueue
双向队列(双向链表实现,jedisPool用的正是这个)
LinkedBlockingQueue
队列(单链表) 使用频率高
ArrayBlockingQueue
限制大小的队列
SynchronousQueue
空集合,put必须等待一个take,Executors.newCachedThreadPool();用的正是这个
ScheduledThreadPoolExecutor.DelayedWorkQueue
内部类不常用
线程池的几个例子
API
返回类型
说明
Executors.newFixedThreadPool(nThreads);
ExecutorService
固定线程数的线程池,不可伸缩
Executors.newSingleThreadExecutor
ExecutorService
单线程,等同于newFixedThreadPool(1)
Executors.newCachedThreadPool()
ExecutorService
相当于无限线程,空闲线程默认60秒超时销毁,适合于短任务
Executors.newScheduledThreadPool(corePoolSize);
ScheduledExecutorService
支持定时周期执行任务
上面已经给出了Executors.newCacheThreadExector的例子
下面给是其他几个API的
串行Executors.newSingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
}
固定大小Executors.newFixedThreadPool(int nThreads)
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
我们怎么优雅的使用线程池和他的接口?
public interface ThreadPool {
Executor getExecutor();
}
public class FixedThreadPool implements ThreadPool {
public Executor getExecutor() {
String name = ThreadPoolConstants.DEFAULT_THREAD_NAME;
int threads = ThreadPoolConstants.DEFAULT_THREADS;
int queues = ThreadPoolConstants.DEFAULT_QUEUES;
return new ThreadPoolExecutor(threads, threads, 0, TimeUnit.MILLISECONDS,
queues == 0 ? new SynchronousQueue() :
(queues < 0 ? new LinkedBlockingQueue()
: new LinkedBlockingQueue(queues)),
new NamedThreadFactory(name, true), new AbortPolicyWithReport(name));
}
}
体会下