=java中创建线程池有哪些方式==
1.使用ThreadPoolExecutor(jdk中提供的线程池的类)
//corePoolSize:核心线程数.
//maximumPoolSize:最大线程数.
//keepAliveTime:临时线程存活时间.
//unit:临时线程存活时间的单位.
//workQueue:工作队列(阻塞队列).
//threadFactory:线程工厂.
//拒绝策略
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
核心线程数设置多少?
CPU密集型(运算): CPU核数+1
IO密集型(频繁和磁盘进行交互): 2 * CPU核数
线程池工作流程?
threadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
System.out.println("任务执行了");
}
});
1.判断核心线程是否有空闲,有:创建线程执行任务.
2.否(所有核心线程都在执行任务): 将任务加入阻塞队列
3.阻塞队列满了,创建临时线程执行任务.
4.没有空闲临时线程(所有临时线程都在执行任务)
5.触发线程池的拒绝策略
拒绝策略:
AbortPolicy:抛异常
CallerRunsPolicy:让线程池的使用者(线程)执行任务。
DiscardPolicy:将任务丢弃
DiscardOldestPolicy:将阻塞队列头部的任务丢弃,将当前任务加入阻塞队列。
2.使用Executors
//核心线程数=最大线程数
//没有临时线程
//LinkedBlockingQueue 无界队列---->OOM
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
//核心线程数=最大线程数=1
//单线程的线程池,仅仅允许并发运行一个任务。
//LinkedBlockingQueue 无界队列---->OOM
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
//临时线程无限------------->OOM
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
Executors存在OOM风险,公司禁止使用.
你的程序中哪里用到了线程池,你是怎么用的?
Spring-------->ThreadPoolTaskExecutor
1.启动类---->@EnableAsync
2.期望某个方法在线程池的子线程中执行 @Async