面试题答案
一键面试- 工作流程:
- 当通过
Executors.newFixedThreadPool
创建固定数目线程池时,会创建指定数量的线程。例如,ExecutorService executor = Executors.newFixedThreadPool(3);
就创建了一个包含3个线程的线程池。 - 当提交新任务时:
- 如果此时线程池中有空闲线程,新任务会立即被分配给其中一个空闲线程执行。比如提交任务
Runnable task1 = () -> System.out.println("Task 1"); executor.submit(task1);
,若3个线程中有空闲的,task1
就会被该空闲线程执行。 - 如果线程池中的线程都处于忙碌状态,新任务会被放入任务队列中等待。假设3个线程都在执行任务,再提交
Runnable task2 = () -> System.out.println("Task 2"); executor.submit(task2);
,task2
就会进入任务队列。 - 当某一线程完成其当前任务,它会从任务队列中取出一个新任务并执行。比如线程1执行完任务,就会从任务队列中取出
task2
执行(如果task2
是队列中的第一个任务)。
- 如果此时线程池中有空闲线程,新任务会立即被分配给其中一个空闲线程执行。比如提交任务
- 当通过
- 任务队列的作用:
- 缓冲任务:当线程池中的线程都在忙碌时,任务队列可以暂时存放新提交的任务,避免任务丢失。例如系统高峰期,短时间内有大量任务提交,任务队列就可以作为缓冲区。
- 实现任务调度:任务队列通常遵循一定的排队策略,如先进先出(FIFO)。默认情况下,
Executors.newFixedThreadPool
使用的是无界的LinkedBlockingQueue
,按照任务提交的顺序来执行任务,保证了任务执行的顺序性。这在一些需要按顺序处理任务的场景中非常重要,比如对数据进行顺序处理的任务。