1.线程池创建方式
1)通过Executors创建线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorServiceDemo {
static ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
executorService.execute(new RunableDemo());
}
}
2)原生方式实现
此处注意LinkedBlockingDeque的默认大小是Integer.MAX_VALUE,在使用是要注意给初始化大小,否则可能会导致内存占满的问题
import java.util.concurrent.*;
public class ExecutorServiceDemo {
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor =
new ThreadPoolExecutor(10, 20, 30, TimeUnit.SECONDS, new LinkedBlockingDeque<>(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
threadPoolExecutor.allowCoreThreadTimeOut(true);
}
}
ThreadPoolExecutor继承了AbstractExecutorService类,而AbstractExecutorService类实现了ExecutorService接口。其本质与Executors创建出的线程池返回的是同一个对象ExecutorService
通过ThreadPoolExecutor创建线程池有七大参数
(1)corePoolSize:线程池保持的线程数量,即使这些线程是空闲状态,也不会被释放,除非设置了
allowCoreThreadTimeOut参数
threadPoolExecutor.allowCoreThreadTimeOut(true);
(2)maximumPoolSize:线程池允许存在的最大线程数量
(3)keepAliveTime:存活时间,当前线程数量大于核心线程数时,如果非核心线程在此时间间隔中 未接收处理任务时,将会被释放
(4)unit:时间单位
(5)workQueue:阻塞队列,当任务较多,当前线程池线程不能全部处理时,将任务放入队中,
当线程池中有空闲线程时,再从队列中取出任务执行
(6)threadFactory:线程创建工厂
(7)handler:拒绝策略,用于处理线程全部被占用且队列存满后对再提交任务的处理
2.线程执行流程
(1)线程池创建,准备好core数量的核心线程,准备接受任务
(2)新任务需要处理,空闲的核心线程处理任务
1.当核心线程全部被占用时,就将提交的任务存放到阻塞队列中,空闲的核心线程会到阻塞 队列中去获取任务执行
2.当提交的任务较多,核心线程数都不处于空闲状态,且阻塞队列也已经被存满了,线程池 开始创建新的线程去执行任务,但是会保证线程池中的线程数不会大于maximumPoolSize
3.如果任务多,线程池已经达到了最大线程数,且都在处理任务,则其他提交的任务就会被 执行拒绝策略
(3)当非核心线程在keepAliveTime时间间隔内未接受到任务时,则非核心线程会被释放
3.场景分析
eg:如果一个线程池的core数量是7,maximumPoolSize是20,workQueue为50,如果有100个任务并发提交到线程池,线程池应该是怎么分配
此时有7个任务会被核心线程执行,这时其他50个任务会被存放到workQueue中,这时,核心线程全部被占用且阻塞队列已经存满,线程池会新开线程去处理剩下的43个任务,但是线程池最多只能有20个线程,而7个是核心线程,这时最多只能开13个线程去执行剩下的任务,这样就还会有30个线程会被执行拒绝策略。
4.Executors可创建的4种线程池
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}