if (!t.isInterrupted() && w.tryLock()) {

try {

t.interrupt();

} catch (SecurityException ignore) {

} finally {

w.unlock();

}

}

if (onlyOne)

break;

}

} finally {

mainLock.unlock();

}

}

2、为什么要调用tryTerminate()?

tryTerminate()不会强行终止线程池,当workerCount为0,workerQueue为空时:

  1. 状态流转到TIDYING

  2. 然后调用钩子函数terminated()

  3. 状态从TIDYING流转到TERMINATED

  4. 调用termination.sinaglAll(),通知前面阻塞在awaitTermination的所有调用者线程。

final void tryTerminate() {

for (;😉 {

int c = ctl.get();

if (isRunning© ||

runStateAtLeast(c, TIDYING) ||

(runStateOf© == SHUTDOWN && ! workQueue.isEmpty()))

return;

if (workerCountOf© != 0) { // Eligible to terminate

interruptIdleWorkers(ONLY_ONE);

return;

}

//1.当workQueue为空,workerCount为空时,cas流转状态为TIDYING

//2.并调用了一个空钩子函数terminated

//3.最终将状态流转为TERMINATED,并通知awaitTermination

final ReentrantLock mainLock = this.mainLock;

mainLock.lock();

try {

if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {

try {

terminated();

} finally {

ctl.set(ctlOf(TERMINATED, 0));

termination.signalAll();

}

return;

}

} finally {

mainLock.unlock();

}

// else retry on failed CAS 自旋

}

}

3、termination.signalAll()唤醒的是什么?

awaitTermination()逻辑很简单,就是重复判断runState是否到达最终状态TERMINATED,如果是直接返回true,如果不是,调用termination.awaitNanos(nanos)阻塞一段时间,苏醒后再判断一次,如果runStateTERMINATED返回true,否则返回false。

/**

  • Wait condition to support awaitTermination

*/

private final Condition termination = mainLock.newCondition();

public boolean awaitTermination(long timeout, TimeUnit unit)

throws InterruptedException {

long nanos = unit.toNanos(timeout);

final ReentrantLock mainLock = this.mainLock;

mainLock.lock();

try {

for (;😉 {

判断当前的runstate是否大于等于TERMINATED

if (runStateAtLeast(ctl.get(), TERMINATED))

return true;

if (nanos <= 0)

return false;

//如果不是TERMINATED,将等待nanos

nanos = termination.awaitNanos(nanos);

}

} finally {

mainLock.unlock();

}

}

三、shutdownNow()将runState流转为STOP


shutdownNow()shutdown()相似,主要做了5步:

  1. 检查是否有中断线程池权限。

  2. 设置runStatusSTOP

  3. 中断所有工作线程。

  4. 清空工作队列。

  5. 尝试终止线程池。

public List shutdownNow() {

List tasks;

final ReentrantLock mainLock = this.mainLock;

mainLock.lock();

try {

//1.检查是否有shutdown权限

checkShutdownAccess();

//2.设置runStatus为stop

advanceRunState(STOP);

//3.给worders发送终止信号

interruptWorkers();

//4.清空阻塞队列

tasks = drainQueue();

} finally {

mainLock.unlock();

}

//5.尝试终止线程池

tryTerminate();

return tasks;

}

四、shutdown()和shutdownNow()的区别


shutdownNow()shutdown()不同之处在于:

  • shutdownNow()会终止所有工作线程,不管是空闲还是正在运行。

  • shutdownNow()会清空阻塞队列。

private void interruptWorkers() {

final ReentrantLock mainLock = this.mainLock;

mainLock.lock();

try {

for (Worker w : workers)

w.interruptIfStarted();

} finally {

mainLock.unlock();

}

}

private List drainQueue() {

BlockingQueue q = workQueue;

ArrayList taskList = new ArrayList();

//删除所有元素并加入到taskList

q.drainTo(taskList);

if (!q.isEmpty()) {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

在面试前我整理归纳了一些面试学习资料,文中结合我的朋友同学面试美团滴滴这类大厂的资料及案例

MyBatis答案解析
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

大家看完有什么不懂的可以在下方留言讨论也可以关注。

觉得文章对你有帮助的话记得关注我点个赞支持一下!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
些面试学习资料,文中结合我的朋友同学面试美团滴滴这类大厂的资料及案例
[外链图片转存中…(img-0jZRIYvh-1711863103041)]

[外链图片转存中…(img-4oHjt8VH-1711863103042)]
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

大家看完有什么不懂的可以在下方留言讨论也可以关注。

觉得文章对你有帮助的话记得关注我点个赞支持一下!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

Logo

一站式 AI 云服务平台

更多推荐