Ending
Tip:由于文章篇幅有限制,下面还有20个关于MySQL的问题,我都复盘整理成一份pdf文档了,后面的内容我就把剩下的问题的目录展示给大家看一下
如果觉得有帮助不妨【转发+点赞+关注】支持我,后续会为大家带来更多的技术类文章以及学习类文章!(阿里对MySQL底层实现以及索引实现问的很多)
吃透后这份pdf,你同样可以跟面试官侃侃而谈MySQL。其实像阿里p7岗位的需求也没那么难(但也不简单),扎实的Java基础+无短板知识面+对某几个开源技术有深度学习+阅读过源码+算法刷题,这一套下来p7岗差不多没什么问题,还是希望大家都能拿到高薪offer吧。
BlockingQueue workQueue,ThreadFactory threadFactory);
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
BlockingQueue workQueue,RejectedExecutionHandler handler);
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
BlockingQueue workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
…
}
由以上代码可知,ThreadPoolExcutor总共有四个构造函数,其中前三个构造函数都是调用了最后一个构造函数的实现。
各个参数代表的含义:
(1)coolPoolSize:常驻核心线程数。
(2)maximumPoolSize:线程池维护最大线程数。
(3)keepAliveTime:线程池维护线程允许的空闲时间。
(4)unit:空闲时间单位。
(5)workQueue:线程池使用的任务缓冲队列。
(6)threadFactory:线程工厂,用于创建线程。
(7)handler:当线程任务达到队列上限时的线程池任务拒绝策略。
下面说明下ThreadPoolExecutor线程池的工作流程,当线程任务进入线程池时,它是通过execute()方法向线程池提交一个线程任务,其中提交的为Runnable对象。
当线程任务被提交到线程池后,当前线程池中的线程数量小于coolPoolSize时,即便线程池中的线程处于空闲状态,线程池也会创建新的线程来执行提交到线程池的任务。
当线程池中的线程数量达到coolPoolSize时,同时缓冲队列尚有空余的时候,新提交的任务将进入workQueue被等待执行。
当线程池中的线程数量大于coolPoolSize,同时任务缓冲队列没有空余且线程小于maximumPoolSize,则线程池会创建临时应急线程处理到来的任务。
当线程池中的线程数量大于coolPoolSize,同时任务缓冲队列没有空余且线程数等于maximumPoolSize,那么线程池则会按照handler指定的策略来处理到来的线程任务。大致流程如下图所示:
3.相关源码分析
下面分析下线程池中executor方法的源码
//原子操作整型类,32位,其中前3位表示线程状态,后29位标识线程的数量
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
public void execute(Runnable command) {
//1.判断执行的线程任务是否空,如果为空抛出空指针异常
if (command == null)
throw new NullPointerException();
//2.获取线程状态以及线程数量
int c = ctl.get();
//3.判断当前线程池数量是否小于corePoolSize,小于则创建新线程
if (workerCountOf© < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
//4.如果线程处于运行状态同时线程可以添加到缓冲队列中
if (isRunning© && workQueue.offer(command)) {
//5.再次检查线程状态(防止上次检查后的线程已销毁或者出现线程池关闭的情况)
int recheck = ctl.get();
//6.如果当前线程状态不是运行状态,那么从队列中删除此任务,同时执行拒绝策略
if (! isRunning(recheck) && remove(command))
reject(command);
//7.否则当前线程池为空,则创建一个线程
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//8.如果队列满了,则新增线程,新增失败则执行拒绝策略
else if (!addWorker(command, false))
reject(command);
}
addWorkder方法
private boolean addWorker(Runnable firstTask, boolean core) {
//1.通过cas来增加线程池中的线程个数
retry:
for (;😉 {
int c = ctl.get();
int rs = runStateOf©;
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;😉 {
int wc = workerCountOf©;
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount©)
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf© != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
//2.并发安全的将任务添加到workers里面,同时启动任务执行
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
//创建worker
知其然不知其所以然,大厂常问面试技术如何复习?
1、热门面试题及答案大全
面试前做足功夫,让你面试成功率提升一截,这里一份热门350道一线互联网常问面试题及答案助你拿offer
2、多线程、高并发、缓存入门到实战项目pdf书籍
3、文中提到面试题答案整理
4、Java核心知识面试宝典
覆盖了JVM 、JAVA集合、JAVA多线程并发、JAVA基础、Spring原理、微服务、Netty与RPC、网络、日志、Zookeeper、Kafka、RabbitMQ、Hbase、MongoDB 、Cassandra、设计模式、负载均衡、数据库、一致性算法 、JAVA算法、数据结构、算法、分布式缓存、Hadoop、Spark、Storm的大量技术点且讲解的非常深入
中…(img-33K1AwMz-1714917117579)]
[外链图片转存中…(img-QA14v66T-1714917117579)]