工作线程池
在 ThreadPoolExecutor 的内部实现中,工作线程池通过 HashSet 实现。在ThreadPoolExecutor 内部对 HashSet 集合内部的数据节点进行增删操作时,通过 ReentrantLock 加锁来实现,保证线程安全问题。
//Worker 为工作线程的包装类
private final HashSet<Worker> workers = new HashSet<>();
//实现线程增删的线程安全的锁
private final ReentrantLock mainLock = new ReentrantLock();
Worker类
继承于AbstractQueuedSynchronizer(AQS):
基于AQS的状态变量 state 来定义当前线程的工作状态,并且可以以线程安全的方式对该状态进行检查和更新。
实现 Runnable 接口:将该worker 线程对象自身作为一个 task 放到 Worker 内部的线程对象 thread 去执行,在 run 方法中定义该工作线程的工作逻辑。
任务的提交
使用 execute 或者 submit 方法来提交任务,execute 方法没有返回值,submit 方法使用 Future 对象作为返回值,可以通过该对象来跟踪这个任务的执行和获取执行结果。
任务提交流程:
-
如果线程池中的线程数少于corePoolSize,则创建一个新线程来执行该任务
-
若线程数达到了corePoolSIze,则将任务放到 workQueue 中。线程池中存在空闲线程时,空闲线程会从任务队列中取出任务并处理
-
若任务等待队列 workQueue 也满了时,如果线程池当前工作线程数小于 maximumPoolSize,则创建新线程执行该任务。
-
否则调用 reject 方法,根据具体的任务拒绝策略处理该任务。任务拒绝策略默认为 AbortPolicy,即在 execute 方法抛异常。
- 任务拒绝策略:AbortPolicy:抛 Abort 异常;CallerRunsPolicy:在主线程直接执行该任务;DiscardPolicy:默默丢弃该任务;DiscardOldestPolicy:移除任务等待队列队头的任务,将该任务添加到队列中。