线程池(四):手写线程池实战(1)

发送成功18xhJaver.com

发送成功19xhJaver.com

发送成功20xhJaver.com

发送成功21xhJaver.com

发送成功22xhJaver.com

发送成功23xhJaver.com

发送成功24xhJaver.com

发送成功25xhJaver.com

发送成功26xhJaver.com

发送成功27xhJaver.com

发送成功28xhJaver.com

发送成功29xhJaver.com

发送成功30xhJaver.com

发送成功31xhJaver.com

发送成功32xhJaver.com

发送成功33xhJaver.com

发送成功34xhJaver.com

发送成功35xhJaver.com

发送成功36xhJaver.com

发送成功37xhJaver.com

发送成功38xhJaver.com

发送成功39xhJaver.com

发送成功40xhJaver.com

发送成功41xhJaver.com

发送成功42xhJaver.com

发送成功43xhJaver.com

发送成功44xhJaver.com

发送成功45xhJaver.com

发送成功46xhJaver.com

发送成功47xhJaver.com

发送成功48xhJaver.com

发送成功49xhJaver.com

发送成功50xhJaver.com

发送成功51xhJaver.com

发送成功52xhJaver.com

发送成功53xhJaver.com

发送成功54xhJaver.com

发送成功55xhJaver.com

发送成功56xhJaver.com

发送成功57xhJaver.com

发送成功58xhJaver.com

发送成功59xhJaver.com

发送成功60xhJaver.com

发送成功61xhJaver.com

发送成功62xhJaver.com

发送成功63xhJaver.com

发送成功64xhJaver.com

发送成功65xhJaver.com

发送成功66xhJaver.com

发送成功67xhJaver.com

发送成功68xhJaver.com

发送成功69xhJaver.com

发送成功70xhJaver.com

发送成功71xhJaver.com

发送成功72xhJaver.com

发送成功73xhJaver.com

发送成功74xhJaver.com

发送成功75xhJaver.com

发送成功76xhJaver.com

发送成功77xhJaver.com

发送成功78xhJaver.com

发送成功79xhJaver.com

发送成功80xhJaver.com

发送成功81xhJaver.com

发送成功82xhJaver.com

发送成功83xhJaver.com

发送成功84xhJaver.com

发送成功85xhJaver.com

发送成功86xhJaver.com

发送成功87xhJaver.com

发送成功88xhJaver.com

发送成功89xhJaver.com

发送成功90xhJaver.com

发送成功91xhJaver.com

发送成功92xhJaver.com

发送成功93xhJaver.com

发送成功94xhJaver.com

发送成功95xhJaver.com

发送成功96xhJaver.com

发送成功97xhJaver.com

发送成功98xhJaver.com

发送成功99xhJaver.com

单线程共用了18404ms

-------分割线-----------------分割线-----------------分割线-----------------分割线-----------------分割线----------

发送成功0xhJaver.com

发送成功1xhJaver.com

发送成功2xhJaver.com

发送成功3xhJaver.com

发送成功4xhJaver.com

发送成功5xhJaver.com

发送成功6xhJaver.com

发送成功7xhJaver.com

发送成功8xhJaver.com

发送成功9xhJaver.com

发送成功10xhJaver.com

发送成功11xhJaver.com

发送成功12xhJaver.com

发送成功13xhJaver.com

发送成功14xhJaver.com

发送成功15xhJaver.com

发送成功16xhJaver.com

发送成功17xhJaver.com

发送成功18xhJaver.com

发送成功19xhJaver.com

发送成功20xhJaver.com

发送成功21xhJaver.com

发送成功22xhJaver.com

发送成功23xhJaver.com

发送成功24xhJaver.com

发送成功25xhJaver.com

发送成功26xhJaver.com

发送成功27xhJaver.com

发送成功28xhJaver.com

发送成功29xhJaver.com

发送成功30xhJaver.com

发送成功31xhJaver.com

发送成功32xhJaver.com

发送成功33xhJaver.com

发送成功34xhJaver.com

发送成功35xhJaver.com

发送成功36xhJaver.com

发送成功37xhJaver.com

发送成功38xhJaver.com

发送成功39xhJaver.com

发送成功40xhJaver.com

发送成功41xhJaver.com

发送成功42xhJaver.com

发送成功43xhJaver.com

发送成功44xhJaver.com

发送成功45xhJaver.com

发送成功46xhJaver.com

发送成功47xhJaver.com

发送成功48xhJaver.com

发送成功49xhJaver.com

发送成功50xhJaver.com

发送成功51xhJaver.com

发送成功52xhJaver.com

发送成功53xhJaver.com

发送成功54xhJaver.com

发送成功55xhJaver.com

发送成功56xhJaver.com

发送成功57xhJaver.com

发送成功58xhJaver.com

发送成功59xhJaver.com

发送成功60xhJaver.com

发送成功61xhJaver.com

发送成功62xhJaver.com

发送成功63xhJaver.com

发送成功64xhJaver.com

发送成功65xhJaver.com

发送成功66xhJaver.com

发送成功67xhJaver.com

发送成功68xhJaver.com

发送成功69xhJaver.com

发送成功70xhJaver.com

发送成功71xhJaver.com

发送成功72xhJaver.com

发送成功73xhJaver.com

发送成功74xhJaver.com

发送成功75xhJaver.com

发送成功76xhJaver.com

发送成功77xhJaver.com

发送成功78xhJaver.com

发送成功79xhJaver.com

发送成功80xhJaver.com

发送成功81xhJaver.com

发送成功82xhJaver.com

发送成功83xhJaver.com

发送成功84xhJaver.com

发送成功85xhJaver.com

发送成功86xhJaver.com

发送成功87xhJaver.com

发送成功88xhJaver.com

发送成功89xhJaver.com

发送成功90xhJaver.com

发送成功91xhJaver.com

发送成功92xhJaver.com

发送成功93xhJaver.com

发送成功94xhJaver.com

发送成功95xhJaver.com

发送成功96xhJaver.com

发送成功97xhJaver.com

发送成功98xhJaver.com

发送成功99xhJaver.com

多线程共用了233ms

从输出结果可以知道 单线程共用18404ms / 150 约等于122 多线程共用233ms /150 约等于1

就相当于发用查询发送一个人的时间解决了这100个人的问题,具体的线程池核心大小数量要根据业务方面自己配置设计

这里面出现了很多和上一篇不会吧,就是你把线程池讲的这么清楚的?没有讲到的知识点,感兴趣的可以去看一看

二、例子重点讲解


文中注释也都清晰明了的,我在解释下几个重要的

2.1.创建任务

自定义任务类实现这个接口并且实现call方法,返回值为传入Callable的类型即可

public class Task implements Callable {

private Integer id;

public Task(Integer id) {

this.id = id;

}

@Override

public String call() throws Exception {

//调用业务方提供的查user的服务,id不同,创建任务的时候就传过来id

User user = DoSomethingService.queryUser(this.id);

//调用业务方提供发送邮件的服务,email不同

String result = DoSomethingService.sendUserEmail(user.getEmail());

return result;

}

}

2.2.构造的任务列表

//构建要做的任务列表,查询出用户来并且发送邮件

List tasks = new ArrayList<>();

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

//传id进去构造不同的任务,业务中有可能是给你个list列表

Task task = new Task(i);

tasks.add(task);

}

2.3.创建线程池提交任务列表并且关闭线程池

//用线程池查询用户发送邮件

ExecutorService executorService = Executors.newFixedThreadPool(100);

//返回任务执行结果

List<Future> futures = null;

try {

//是线程池执行提交的批量任务

futures = executorService.invokeAll(tasks);

} catch (InterruptedException e) {

e.printStackTrace();

}

//关闭线程池

executorService.shutdown();

注:提交任务的时候也可以是submit不过在这样一次提交一个任务,要是有任务列表可以用invokeAll shoutdown和shoutdownNow都可以关闭线程池。但是又很大的区别 shoutdown :不会立刻停止线程池,但是会拒绝处理新来的任务,阻塞队列中的任务等他执行完 shoutdownNow:会立刻停止线程池,拒绝处理新来的任务并且打断正在执行的线程,将阻塞队列中的任务全部清空 总的来说就是shoutdown温柔一点,shoutdownNow粗暴一点

2.3.1线程池提交callable任务四种方法讲解

关于提交线程池提交callable任务有以下四种方法

  • invokeAll无时间参数

List<Future> invokeAll(Collection<? extends Callable> tasks)

throws InterruptedException;

如果调没有异常发生的话都会调用成功 如果有一个有异常则有异常的调用失败,其余成功

  • invokeAll有时间参数

List<Future> invokeAll(Collection<? extends Callable> tasks,

long timeout, TimeUnit unit)

throws InterruptedException;

当全部任务执行完后超过指定时限后,直接抛出异常

  • invokeAny无时间参数

T invokeAny(Collection<? extends Callable> tasks)

throws InterruptedException, ExecutionException;

invokeAny将第一个完成的作为结果,或者调用失败则也立即终止其他所有线程。

  • invokeAny有时间参数

T invokeAny(Collection<? extends Callable> tasks,

long timeout, TimeUnit unit)

throws InterruptedException, ExecutionException, TimeoutException;

若设置了超时时间,未超时完成则返回正常结果,否则报错

2.4.解析任务结果

//存放任务结果的集合

List results = new ArrayList<>();

//遍历这个任务执行结果

for (Future result:futures) {

//如果这个任务结束了

if (result.isDone()){

String s = null;

try {

//得到这个任务的处理结果,得不到会一直阻塞

s = result.get();

} catch (ExecutionException e) {

e.printStackTrace();

最后

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

腾讯、字节跳动、阿里、百度等BAT大厂 2019-2021面试真题解析

资料太多,全部展示会影响篇幅,暂时就先列举这些部分截图

若设置了超时时间,未超时完成则返回正常结果,否则报错

2.4.解析任务结果

//存放任务结果的集合

List results = new ArrayList<>();

//遍历这个任务执行结果

for (Future result:futures) {

//如果这个任务结束了

if (result.isDone()){

String s = null;

try {

//得到这个任务的处理结果,得不到会一直阻塞

s = result.get();

} catch (ExecutionException e) {

e.printStackTrace();

最后

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

[外链图片转存中…(img-aFKHWRhf-1726057654135)]

腾讯、字节跳动、阿里、百度等BAT大厂 2019-2021面试真题解析

[外链图片转存中…(img-a5eYHOnT-1726057654135)]

资料太多,全部展示会影响篇幅,暂时就先列举这些部分截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值