Java 并发面试题, Java 并发库中提供了哪些线程池实现?它们有什么区别?
Java 并发面试题, Java 并发库中提供了哪些线程池实现?它们有什么区别?
QA
Step 1
Q:: Java 并发库中提供了哪些线程池实现?它们有什么区别?
A:: Java 并发库中提供了几种常见的线程池实现:
1.
FixedThreadPool:一个固定大小的线程池。线程数量保持不变,如果有新的任务提交且所有线程都在工作,新任务会被放入等待队列中,直到有空闲线程。
2.
CachedThreadPool:一个可缓存的线程池。线程数量不固定,适用于执行很多短期异步任务。空闲的线程会被回收,当任务增加时,可以创建新的线程。
3.
SingleThreadExecutor:只有一个线程的线程池。所有任务会被顺序执行,适用于需要保证任务执行顺序的场景。
4.
ScheduledThreadPool:支持定时或周期性任务调度的线程池。适用于需要定时执行任务的场景。
Step 2
Q:: FixedThreadPool和CachedThreadPool的使用场景有什么不同?
A:: FixedThreadPool适用于已知并发任务数量的场景,比如处理固定数量的任务或限制资源使用的场合。而CachedThreadPool适用于执行很多短期任务,且任务数量不确定的场景,因为它能够动态调整线程数量以应对任务负载。
Step 3
Q:: 如何创建一个自定义线程池?
A:: 可以使用ThreadPoolExecutor类来创建一个自定义线程池。构造方法允许指定核心线程数、最大线程数、空闲线程存活时间、时间单位、任务队列、线程工厂以及拒绝策略等参数。 示例代码:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(),
new ThreadFactory() {
public Thread newThread(Runnable r) {
return new Thread(r);
}
},
new ThreadPoolExecutor.AbortPolicy()
);
Step 4
Q:: Java中的线程池如何管理任务队列?
A:: Java中的线程池通过内部维护的任务队列来管理待执行的任务。常见的任务队列有:
1.
LinkedBlockingQueue:一个基于链表的有界(或无界)阻塞队列。
2.
ArrayBlockingQueue:一个基于数组的有界阻塞队列。
3.
SynchronousQueue:一个不存储元素的阻塞队列,每个插入操作必须等待一个相应的移除操作,反之亦然。
4.
PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列。
Step 5
Q:: 什么是线程池的拒绝策略?有哪些常见的拒绝策略?
A:: 当线程池无法接受新的任务时,会使用拒绝策略来处理这些任务。常见的拒绝策略包括:
1.
AbortPolicy(默认):直接抛出RejectedExecutionException,阻止系统正常工作。
2.
CallerRunsPolicy:由调用线程处理该任务。
3.
DiscardPolicy:直接丢弃任务,不给予任何处理。
4.
DiscardOldestPolicy:丢弃队列中最旧的未处理任务,然后尝试重新提交当前任务。