发送成功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)]
资料太多,全部展示会影响篇幅,暂时就先列举这些部分截图