点击领取优惠~
565 字
3 分钟
线程池原理
线程池原理
从数据结构的角度来看,线程池主要使用了阻塞队列(BlockingQueue)和HashSet集合构成。 从任务提交的流程角度来看,对于使用线程池的外部来说,线程池的机制是这样的:
1、如果正在运行的线程数 < coreSize,马上创建核心线程执行该task,不排队等待;2、如果正在运行的线程数 >= coreSize,把该task放入阻塞队列;3、如果队列已满 && 正在运行的线程数 < maximumPoolSize,创建新的非核心线程执行该task;4、如果队列已满 && 正在运行的线程数 >= maximumPoolSize,线程池调用handler的reject方法拒绝本次提交。理解记忆:1-2-3-4对应(核心线程->阻塞队列->非核心线程->handler拒绝提交)。
线程池的线程复用:
这里就需要深入到源码addWorker():它是创建新线程的关键,也是线程复用的关键入口。最终会执行到runWoker,它取任务有两个方式:
- firstTask:这是指定的第一个runnable可执行任务,它会在Woker这个工作线程中运行执行任务run。并且置空表示这个任务已经被执行。
- getTask():这首先是一个死循环过程,工作线程循环直到能够取出Runnable对象或超时返回,这里的取的目标就是任务队列workQueue,对应刚才入队的操作,有入有出。
其实就是任务在并不只执行创建时指定的firstTask第一任务,还会从任务队列的中通过getTask()方法自己主动去取任务执行,而且是有/无时间限定的阻塞等待,保证线程的存活。
信号量
semaphore 可用于进程间同步也可用于同一个进程间的线程同步。
可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。
线程池原理