Java线程池
线程池的执行过程
-
当向线程池提交一个新的任务,线程池首先判断核心线程池的线程是否都在执行任务。如果不是,创建一个新的工作线程来执行任务。如果核心线程的线程都在执行任务,则进入下一个流程。
-
线程池判断工作队列是否已经满了,如果工作队列没有满,则将新提交的任务存储在这个工作队列里如果工作队列满了,则进入下一个流程
-
线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务。
线程池创建的参数
public ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler
)
-
corePoolSize(线程池的基本大小,核心线程池大小):提交一个新的任务到线程池,就会创建一个新的线程来执行任务,即使有空闲线程来执行任务,也会创建线程。直到待执行的任务数大于线程池基本大小就不再创建新的线程。如果调用了线程池的prestartCoreThread()方法,线程池会提前创建并启动所有的基本线程。
-
workQueue(工作队列):用于在执行任务之前保存任务的队列。此队列用于保存向线程池提交的未处理的任务。
- ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按FIFO原则对元素进行排序。
- LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO排序元素,吞吐量通常高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用这个队列。
- SynchronousQueue:一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态。
- DelayedWorkQueue:一个基于延迟时间排序的队列,Executors.newScheduledThreadPool()使用这个队列。
- LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列
- LinkedTransferQueue:一个由链表结构组成的无界阻塞队列
- PriorityBlockingQueue:一个具有优先级的无限阻塞队列
-
maximumPoolSize(线程池最大数量):线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务,如果使用了无界的任务队列这个参数就没有什么效果。
-
ThreadFactory:用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程设置更有意义的名字。
-
RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。
-
AbortPolicy(默认策略):直接抛出异常;
-
CallerRunsPolicy:只用调用者所在线程来运行任务;
-
DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务
-
DiscardPolicy:不处理,丢弃掉
-
-
keepAliveTime(线程活动保持时间): 线程池的工作线程空闲后,保持存活的时间。所以,如果任务很多,并且每个任务执行时间比较短,可以调大时间,提高线程利用率.
-
unit:(线程活动保持时间的单位):可选的单位有天(DAYS)、小时(HOURS)、分钟(MINUTES)、毫秒(MILLISECONDS)、微秒(MICROSECONDS,千分之一毫秒)和纳秒(NANOSECONDS,千分之一微秒)。
向线程池提交任务
- 使用execute() 方法提交。实现了Runable接口的线程
ExecutorService threadPool = Executors.newFixedThreadPool(1);
threadPool.execute(() -> {
//TODO
});
- 使用submit()方法提交。用于提交需要返回值的任务。线程池会返回一个future类型的对象
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task
ExecutorService threadPool = Executors.newFixedThreadPool(1);
Future<String> future = threadPool.submit(() -> "Hello");
try {
String hello = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}finally {
// 关闭线程池
threadPool.shutdown();
}
注:本文参考于《Java并发编程艺术》第九章 Java中的线程池
标签:Java,队列,创建,任务,线程,提交,执行 From: https://www.cnblogs.com/pangcode/p/16737103.html