Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b16f324

Browse files
authored
Merge pull request h2pl#25 from Rorke76753/patch-1
Update Java并发指南12:深度解读 java 线程池设计思想及源码实现.md
2 parents 65e029b + d016975 commit b16f324

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

‎docs/java/currency/Java并发指南12:深度解读 java 线程池设计思想及源码实现.md‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* [AbstractExecutorService](#abstractexecutorservice)
99
* [ThreadPoolExecutor](#threadpoolexecutor)
1010
* [Executors](#executors)
11+
* [Worker获取任务](#getTask)
1112
* [总结](#总结)
1213

1314

@@ -1275,6 +1276,51 @@ else if (!addWorker(command, false))
12751276

12761277
> SynchronousQueue 是一个比较特殊的 BlockingQueue,其本身不储存任何元素,它有一个虚拟队列(或虚拟栈),不管读操作还是写操作,如果当前队列中存储的是与当前操作相同模式的线程,那么当前操作也进入队列中等待;如果是相反模式,则配对成功,从当前队列中取队头节点。具体的信息,可以看我的另一篇关于 BlockingQueue 的文章。
12771278
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+
```
12781324
## 总结
12791325

12801326
我一向不喜欢写总结,因为我把所有需要表达的都写在正文中了,写小篇幅的总结并不能真正将话说清楚,本文的总结部分为准备面试的读者而写,希望能帮到面试者或者没有足够的时间看完全文的读者。

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /