看完这篇,再也不怕面试官问我线程池了,2024年最新oppo前端外包面试

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

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

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

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

pool-1-thread-2-------running

pool-1-thread-6-------running

pool-1-thread-1-------running

pool-1-thread-3-------running

pool-1-thread-5-------running

pool-1-thread-4-------running

pool-1-thread-7-------running

pool-1-thread-11-------running

pool-1-thread-9-------running

pool-1-thread-10-------running

pool-1-thread-17-------running

pool-1-thread-15-------running

pool-1-thread-18-------running

pool-1-thread-16-------running

pool-1-thread-8-------running

pool-1-thread-20-------running

pool-1-thread-13-------running

pool-1-thread-19-------running

pool-1-thread-14-------running

pool-1-thread-12-------running

4.2 newFixedThreadPool

源码实现:

public static ExecutorService newFixedThreadPool(int nThreads) {

return new ThreadPoolExecutor(nThreads, nThreads,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue());

}

案例:

public class FixedThreadPoolDemo {

public static void main(String[] args) {

//创建线程池,最多允许五个线程执行

ExecutorService executorService = Executors.newFixedThreadPool(5);

for (int i = 0; i < 20; i++) {

//提交任务

executorService.execute(new Task());

}

//启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务

executorService.shutdown();

}

}

输出结果:

我们可以看到其中的线程是每五个(pool-1-thread-1到pool-1-thread-5)一执行,在当前执行的线程运行中,最多允许五个线程进行执行

pool-1-thread-4-------running

pool-1-thread-2-------running

pool-1-thread-1-------running

pool-1-thread-3-------running

pool-1-thread-5-------running

pool-1-thread-4-------running

pool-1-thread-5-------running

pool-1-thread-3-------running

pool-1-thread-2-------running

pool-1-thread-1-------running

pool-1-thread-4-------running

pool-1-thread-2-------running

pool-1-thread-1-------running

pool-1-thread-3-------running

pool-1-thread-5-------running

pool-1-thread-4-------running

pool-1-thread-5-------running

pool-1-thread-2-------running

pool-1-thread-1-------running

pool-1-thread-3-------running

4.3 newSingleThreadExecutor

源码实现:

public static ExecutorService newSingleThreadExecutor() {

return new FinalizableDelegatedExecutorService

(new ThreadPoolExecutor(1, 1,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue()));

}

案例:

public class SingleThreadPoolDemo {

public static void main(String[] args) {

ExecutorService executorService = Executors.newSingleThreadExecutor();

for (int i = 0; i < 20; i++) {

//提交任务

executorService.execute(new Task());

}

//启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务

executorService.shutdown();

}

}

结果输出:

我们可以看到每次都是线程1输出结果

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

pool-1-thread-1-------running

五、线程池的具体实现:ScheduledThreadPoolExecutor


5.1 newScheduledThreadPool

案例:

public static void main(String[] args) {

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);

// for (int i = 0; i < 20; i++) {

System.out.println(System.currentTimeMillis());

scheduledExecutorService.schedule(new Runnable() {

@Override

public void run() {

System.out.println(“延迟三秒执行”);

System.out.println(System.currentTimeMillis());

}

},3, TimeUnit.SECONDS);

// }

scheduledExecutorService.shutdown();

}

}

输出结果:

1606744468814

延迟三秒执行

1606744471815

5.2 newSingleThreadScheduledExecutor

案例:

public static void main(String[] args) {

ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();

scheduledExecutorService.scheduleAtFixedRate(new Runnable() {

int i = 1;

@Override

public void run() {

System.out.println(i);

i++;

}

},0,1, TimeUnit.SECONDS);

// scheduledExecutorService.shutdown();

}

输出结果:

1

2

3

4

5

六、线程池的生命周期


在这里插入图片描述

一般来说线程池只有两种状态,一种是Running,一种是TERMINATED,图中间的都是过渡状态

Running:能接受新提交的任务,并且也能处理阻塞队列中的任务

SHUTDOWN:关闭状态,不再接受新提交的任务,但却可以继续处理阻塞队列中已保存的任务

STOP:不能接受新任务,也不处理队列中的任务,会中断正在处理任务的线程

TIDYING:如果所有的任务都已终止了,workerCount(有效线程数)为0.线程池进入该状态后会调用terminated()方法进入TERMINATED状态

TERMINATED:在terminated()方法执行完成后进入该状态,默认terminated()方法中什么也没有做

七、线程池的创建


7.1 Executors 源码

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue,

ThreadFactory threadFactory,

RejectedExecutionHandler handler)

7.2 参数说明

corePoolSize:核心线程池的大小

maximumPoolSize:线程池能创建线程的最大个数

keepAliveTime:空闲线程存活时间

unit:时间单位,为keepAliveTime指定时间单位

workQueue:阻塞队列,用于保存任务的阻塞队列

threadFactory:创建线程的工程类

handler:饱和策略(拒绝策略)

八、阻塞队列


在这里插入图片描述

ArrayBlockingQueue:

基于数组的阻塞队列实现,在ArrayBlockingQueue内部,维护了一个定长数组,以便缓存队列中的数据对象,这是-个常用的阻塞队列,除了一个定长数组外,ArrayBlockingQueue内部还保存着两个整形变量,分别标识着队列的头部和尾部在数组中的位置。

ArrayBlockingQueue在生产者放入数据和消费者获取数据,都是共用同一个锁对象,由此也意味着两者无法真正并行运行,这点尤其不同于LinkedBlockingQueue;按照实现原理来分析,ArrayBlockingQueue完全可以采用分离锁,从而实现生产者和消费者操作的完全并行运行。Doug Lea之所以没这样去做,也许是因为ArrayBlockingQueue的数据写入和获取操作已经足够轻巧,以至于引入独立的锁机制,除了给代码带来额外的复杂性外,其在性能上完全占不到任何便宜。

ArrayBlockingQueue和LinkedBlockingQueue间还有一个明显的不同之处在于,前者在插入或删除元素时不会产生或销毁任何额外的对象实例,而后者则会生成一个额外的Node对象。这在长时间内需要高效并发地处理大批量数据的系统中,其对于GC的影响还是存在一定的区别。而在创建ArrayBlockingQueue时,我们还可以控制对象的内部锁是否采用公平锁,默认采用非公平锁。

LinkedBlockingQueue:

基于链表的阻塞队列,同ArrayListBlockingQueue类似,其内部也维持着一个数据缓冲队列(该队列由一个链表构成),当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回;只有当队列缓冲区达到最大值缓存容量时( LinkedBlockingQueue可以通过构造函数指定该值),才会阻塞生产者队列,直到消费者从队列中消费掉─份数据,生产者线程会被唤醒,反之对打于消费者这端的处理也基于同样的原理。而

LinkedBlockingQueue之所以能够高效的处理并发数据,还因为其对于生产者端和消费者端分别采用了独立的锁来控制数据同步,这也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能。

DelayQueue:

DelayQueue中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元素。DelayQueue是一个没有大小限制的队列,因此往队列中插入数据的操作(生产者)永远不会被阻塞,而只有获取数据的操作(消费者)才会被阻塞。

使用场景︰

DelayQueue使用场景较少,但都相当巧妙,常见的例子比如使用一个DelayQueue来管理一个超时未响应的连接队列。

总结:心得体会

既然选择这个行业,选择了做一个程序员,也就明白只有不断学习,积累实战经验才有资格往上走,拿高薪,为自己,为父母,为以后的家能有一定的经济保障。

学习时间都是自己挤出来的,短时间或许很难看到效果,一旦坚持下来了,必然会有所改变。不如好好想想自己为什么想进入这个行业,给自己内心一个答案。

面试大厂,最重要的就是夯实的基础,不然面试官随便一问你就凉了;其次会问一些技术原理,还会看你对知识掌握的广度,最重要的还是你的思路,这是面试官比较看重的。

最后,上面这些大厂面试真题都是非常好的学习资料,通过这些面试真题能够看看自己对技术知识掌握的大概情况,从而能够给自己定一个学习方向。包括上面分享到的学习指南,你都可以从学习指南里理顺学习路线,避免低效学习。

大厂Java架构核心笔记(适合中高级程序员阅读):

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
果,一旦坚持下来了,必然会有所改变。不如好好想想自己为什么想进入这个行业,给自己内心一个答案。

面试大厂,最重要的就是夯实的基础,不然面试官随便一问你就凉了;其次会问一些技术原理,还会看你对知识掌握的广度,最重要的还是你的思路,这是面试官比较看重的。

最后,上面这些大厂面试真题都是非常好的学习资料,通过这些面试真题能够看看自己对技术知识掌握的大概情况,从而能够给自己定一个学习方向。包括上面分享到的学习指南,你都可以从学习指南里理顺学习路线,避免低效学习。

大厂Java架构核心笔记(适合中高级程序员阅读):

[外链图片转存中…(img-fAlGCO1u-1713479473001)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-2XLg7wvl-1713479473002)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值