多线程的项目实战
//1.CountDownLatch,计数
CountDownLatch doneSignal = new CountDownLatch(1000);
//2.创建线程池来存放线程,以防考生数量太多创建太多线程,占用过多资源
ThreadPoolExecutor executor = new ThreadPoolExecutor(50, 150, 60000, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>());
for (ExaminationModel examineeModel : notExamStudentInfo) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// 。。。。。。打印试卷的逻辑
} finally {
// 每执行完一个线程,数量减1
doneSignal.countDown();
}
}
});
//3. 将任务添加到线程池
executor.execute(thread);
}
// 4. 为了让所有的试卷都生成之后再执行压缩以及删除PDF文件,所以需要让主线程等待子线程执行完之后再执行await
try {
// 主线程等待
doneSignal.await();
System.out.println("线程运行时间:" + (System.currentTimeMillis() - startTime) + "ms");
} catch (InterruptedException e) {
log.error(e.getMessage(), e);
}
//5. 关闭线程池(所有线程执行完关闭线程池)
executor.shutdown();
// 6. 将所有试卷打包zip
boolean flag = fileToZip();
知识点讲解:
之所以用线程池,是因为防止产生过多的线程,从而造成线程来回切换,而造成的形成损失
CountDownLatch:它的作用是允许1或N个线程等待其他线程完成执行,在这用它是因为 要把所有的试卷,打包成zip压缩包,所以主线程要等所有的子线程即生成试卷要执行完才能打包,用到了CountDownLatch的await()和countDown()方法,有关CountDownLatch更多讲解,参见:https://www.cnblogs.com/skywang12345/p/3533887.html
我这创建的核心线程为50,最大线程为150,更具电脑cpu性能设置,执行程序打印线程号,线程号一直超不过50,是因为任务队列使用的是LinkedBlockingDeque,大小为Integer.MAX_VALUE(Integer.MAX_VALUE=7fffffff(十六进制) = 2147483647(十进制)),任务队列一直没有满,具体原因详情参见:https://mp.csdn.net/mdeditor/90082697#
为什么不用join()
使用join()可能出现的问题:
join()后面的代码可能提前完成,这样打包的数据就不全了
join()过程中可能被打断了,这样系统就会抛异常( 因为底层调用的是wait() ),如果不想让程序判断就得做各种异常的判断,比较麻烦
————————————————
版权声明:本文为CSDN博主「王如霜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wrs120/article/details/90634863
本文来自博客园,作者:Lz_蚂蚱,转载请注明原文链接:https://www.cnblogs.com/leizia/p/16010436.html

浙公网安备 33010602011771号