1、任务开始,线程池为空;
image.png
2、先后有7个任务加入到线程池中,正在运行1个,已完成6个
image.png
3、关闭其他线程,关闭线程池
image.png
4、初始化,初始化线程池
image.png
5、不! 这不是线程池的初始化! 而是对三个任务进行计数! COUNT_LIST 用来当作计数器容器。
image.png
[图片上传中...(image.png-fd5528-1541751268686-0)]
6、找到了这个静态ExecutorService,下面需要将其变为非静态的,每次初始化都new一个新的线程池
[图片上传中...(image.png-f90f73-1541751404191-0)]
7、将其变为非静态属性
[图片上传中...(image.png-bba0d0-1541751756414-0)]
8、新增线程池初始化代码
image.png
9、测试,再来看 ES , completed tasks = 0 了, 线程池初始化成功
image.png
10、新问题,处理了 0 条数据 (应>0) 。
只是依赖最后一个线程的结束来确定程序的结束, 导致前置线程异常关闭
image.png
public void start(List<Triplet> taskList) {
try {
for (int i = 0; i < taskList.size(); i++) {
int sum = Integer.parseInt(taskList.get(i).getThread().toString());
for (int k = 0; k < sum; k++) {
ES.execute((Runnable) taskList.get(i).getTask());
}
// 这里,我需要确保前置线程执行完毕后再关闭主线程
try {
if (i == (taskList.size() - 1) && null != taskList.get(i).getSignal()) {
((CountDownLatch) taskList.get(i).getSignal()).await();
}
} catch (InterruptedException e) {
LOGGER.error(e.getMessage());
}
}
} catch (Exception e) {
LOGGER.error(e.getMessage());
} finally {
DIVIDE_DONE_SIGNAL.countDown();
EXTRACTION_DONE_SIGNAL.countDown();
ES.shutdown();
}
}
11、这里有三个任务,前两个任务用来处理数据,最后一个任务用来写入数据库。在加注释的 try内,添加判断条件,当前两个任务都关闭后,才执行 任务3 的关闭。
image.pngimage.png
。。。。。。
12、启动程序,第一次是成功的,后面都是失败。还有其他属性没有被初始化, 队列!用于进程间读写的阻塞队列! 在设置中,线程的结束是按照初始传入的数据条数来判断的,所以队列里的数据会越来越多
[图片上传中...(image.png-5d52db-1541753335885-0)]
13、三个线程
image.png
14、查看三个线程获取到的值,另外两个线程是 null , 但是,当判断为null时, 又向队列插入了两个空值
image.png
image.png
15、删除 else ,测试, 还是 0
image.png
16、计数器未初始化!
image.png
17、使计数器可被实例化 , finished !
[图片上传中...(image.png-e28ab4-1541755586886-0)]
总结:根据项目需求,修改原有代码;忽略了在分布式环境下的很多问题;代码基础薄弱,还需巩固提高。
网友评论