面试题答案
一键面试非阻塞I/O模型下使用线程池实现并发控制
- 总体思路:在非阻塞I/O模型中,当I/O操作不具备条件时,系统调用会立即返回,不会阻塞线程。利用线程池来处理这些I/O操作返回的事件,线程池中的线程负责执行具体的业务逻辑,从而实现并发控制。
- 具体实现:
- 应用程序注册非阻塞I/O事件(如读、写事件)到事件多路复用器(如Linux下的epoll,Windows下的IOCP)。
- 事件多路复用器监测这些事件,当有事件发生时,将对应的任务提交到线程池。
- 线程池中的线程从任务队列中取出任务并执行。
线程池主要参数及其作用
- 核心线程数(Core Pool Size):
- 作用:线程池中会一直存活的线程数量,即使这些线程处于空闲状态,也不会被销毁。当新任务提交到线程池时,如果当前线程池中的线程数小于核心线程数,会创建新的线程来处理任务。
- 最大线程数(Maximum Pool Size):
- 作用:线程池中允许存在的最大线程数量。当任务队列已满且当前线程数小于最大线程数时,会继续创建新线程来处理任务。如果线程数达到最大线程数且任务队列也已满,新任务的处理策略由拒绝策略决定。
- 任务队列(Work Queue):
- 作用:用于存放等待执行的任务。当线程池中的线程数达到核心线程数后,新提交的任务会被放入任务队列中等待执行。常见的任务队列类型有ArrayBlockingQueue(有界队列)、LinkedBlockingQueue(无界队列)、SynchronousQueue(同步队列)等。不同类型的队列对线程池的性能和资源消耗有不同影响。
- 线程存活时间(Keep - Alive Time):
- 作用:当线程池中的线程数量超过核心线程数时,多余的空闲线程在存活时间内如果没有新任务分配,将会被销毁。这个参数可以控制线程池在任务减少时回收资源。
- 时间单位(Time Unit):
- 作用:用于指定线程存活时间的时间单位,如毫秒(MILLISECONDS)、秒(SECONDS)、分钟(MINUTES)等。
- 拒绝策略(Rejected Execution Handler):
- 作用:当任务队列已满且线程数达到最大线程数,新任务无法被接受时,线程池会按照拒绝策略来处理这些任务。常见的拒绝策略有AbortPolicy(直接抛出异常)、CallerRunsPolicy(将任务交回给调用者线程执行)、DiscardPolicy(直接丢弃任务)、DiscardOldestPolicy(丢弃队列中最老的任务,然后尝试提交新任务)。