Java 线程池
java中的线程池
继承关系如下:
/**
继承自AbstractExecutorService
*/
public class ThreadPoolExecutor extends AbstractExecutorService
/**
实现了ExecutorService接口
*/
public abstract class AbstractExecutorService implements ExecutorService
/**
继承扩展了Executor接口,这里具体扩展了:
void shutdown();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException;
*/
public interface ExecutorService extends Executor
public interface Executor {
/**
这里只有一个
void execute(Runnable command);
也就是一个只能执行Runnable任务的线程池
*/
/**
* Executes the given command at some time in the future. The command
* may execute in a new thread, in a pooled thread, or in the calling
* thread, at the discretion of the {@code Executor} implementation.
*
* @param command the runnable task
* @throws RejectedExecutionException if this task cannot be
* accepted for execution
* @throws NullPointerException if command is null
*/
void execute(Runnable command);
}
具体的线程池的实现:
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} or {@code handler} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
/**
使用给定的参数创建一个新的ThreadPoolExecutor
@param corePoolSize:线程池中保留的线程的数量,除非设置了allowCoreThreadTimeOut,否则即使这些空闲的线程没有任务可以执行,这些线程也不会被销毁。
@param maximumPoolSize:线程池中允许存在的最大线程的数量。
@param keepAliveTime:当线程池中线程的数量大于核心线程数量(corePoolSize),这个keepAliveTime是其他的空闲线程可以存活来等待新的任务的最长时间。
@param unit:keepAliveTime的时间单位。
@param workQueue:任务在执行之前将任务保存在这个任务队列中。这个队列是Runnable的泛型约束的。
@param threadFactory:创先线程的工厂类实例。
@param handler:当线程池阻塞的时候,也就是线程没有可用的并且任务队列满了,这时候新来的任务的拒绝策略
*/
常用的阻塞队列
/**
常用的阻塞队列
其中最常用的是LinkedBlockingQueue与SynchronousQueue
*/
ArrayBlockingQueue;基于数组的FIFO队列,使用的时候必须指定大小
LinkedBlockingQueue;基于链表的FIFO队列,如果不指定大小的话大小是Integer.MAX_VALUE
SynchronousQueue;一种阻塞队列,其中每个 put 必须等待一个 take,反之亦然。同步队列没有任何内部容量,甚至连一个队列的容量都没有。
线程拒绝策略
当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
线程池的关闭:
- shutdown():会等待现有的任务执行完,其中也包括任务队列中的任务执行完
- shutdownNow():立即结束线程,尝试打断正在执行的任务且清空任务队列。
线程池的运行原理:
任务来了之后使用核心线程执行任务,当核心线程用完了之后会将新来的任务放到任务队列中,如果这时候还有线程来了,就又开始创建新的线程去执行队列中的任务,如果线程数要大于最大线程数量,这时候就开始使用任务的拒绝策略了。
java中包装好的一些线程池
Executors.newCachedThreadPool(); //创建一个缓冲池,缓冲池容量大小为Integer.MAX_VALUE
Executors.newSingleThreadExecutor(); //创建容量为1的缓冲池
Executors.newFixedThreadPool(int); //创建固定容量大小的缓冲池
三个线程池的具体实现
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}