|
8 | 8 | * [AbstractExecutorService](#abstractexecutorservice)
|
9 | 9 | * [ThreadPoolExecutor](#threadpoolexecutor)
|
10 | 10 | * [Executors](#executors)
|
| 11 | + * [Worker获取任务](#getTask) |
11 | 12 | * [总结](#总结)
|
12 | 13 |
|
13 | 14 |
|
@@ -1275,6 +1276,51 @@ else if (!addWorker(command, false))
|
1275 | 1276 |
|
1276 | 1277 | > SynchronousQueue 是一个比较特殊的 BlockingQueue,其本身不储存任何元素,它有一个虚拟队列(或虚拟栈),不管读操作还是写操作,如果当前队列中存储的是与当前操作相同模式的线程,那么当前操作也进入队列中等待;如果是相反模式,则配对成功,从当前队列中取队头节点。具体的信息,可以看我的另一篇关于 BlockingQueue 的文章。
|
1277 | 1278 |
|
| 1279 | +## getTask |
| 1280 | + 前文已经分析了`runWorker`方法,我们可以看到该方法中有一行这样的代码 |
| 1281 | + ```java |
| 1282 | + //... |
| 1283 | + while (task != null || (task = getTask()) != null) { |
| 1284 | + //... |
| 1285 | + ``` |
| 1286 | + 这一行代码如果`task!=null`,即前一个条件为`true`时意味着传入的一个非`null`的`task`,同时代码会优化使得第二个条件不去执行;那么前一个条件为`false`时,就会尝试调用`getTask`方法。在这一个方法中,`worker`会尝试从工作队列中取出任务来进行执行。 |
| 1287 | + ```java |
| 1288 | + private Runnable getTask() { |
| 1289 | + boolean timedOut = false; |
| 1290 | + //不断尝试获得任务 |
| 1291 | + for (;;) { |
| 1292 | + int c = ctl.get(); |
| 1293 | + int rs = runStateOf(c); |
| 1294 | + // 前文已有相似的状态,这里不再赘述 |
| 1295 | + if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) { |
| 1296 | + decrementWorkerCount(); |
| 1297 | + return null; |
| 1298 | + } |
| 1299 | + int wc = workerCountOf(c); |
| 1300 | + //是否设置了允许核心线程超时(设置了之后核心线程在超时后会销毁),或者当前worker数量比核心池大 |
| 1301 | + boolean timed = allowCoreThreadTimeOut || wc > corePoolSize; |
| 1302 | + |
| 1303 | + if ((wc > maximumPoolSize || (timed && timedOut))&& (wc > 1 || workQueue.isEmpty())) { |
| 1304 | + if (compareAndDecrementWorkerCount(c)) |
| 1305 | + return null; |
| 1306 | + continue; |
| 1307 | + } |
| 1308 | + try { |
| 1309 | + //是否设置了允许核心线程超时(设置了之后核心线程在超时后会销毁),或者当前worker数量比核心池大 |
| 1310 | + //如果是调用queue的poll(int,TimeUnit)方法,否则直接调用take方法 |
| 1311 | + Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take(); |
| 1312 | + //能获取到非空的任务就返回 |
| 1313 | + //对于不设置允许核心线程超时的情况,核心线程就一直在getTask的这个循环中 |
| 1314 | + //一直等待有新的任务来执行 |
| 1315 | + if (r != null) |
| 1316 | + return r; |
| 1317 | + timedOut = true; |
| 1318 | + } catch (InterruptedException retry) { |
| 1319 | + timedOut = false; |
| 1320 | + } |
| 1321 | + } |
| 1322 | + } |
| 1323 | + ``` |
1278 | 1324 | ## 总结
|
1279 | 1325 |
|
1280 | 1326 | 我一向不喜欢写总结,因为我把所有需要表达的都写在正文中了,写小篇幅的总结并不能真正将话说清楚,本文的总结部分为准备面试的读者而写,希望能帮到面试者或者没有足够的时间看完全文的读者。
|
|
0 commit comments