多线程Java主类在线程执行之前结束
我有一个多线程执行,我想跟踪并打印执行时间,但当我执行代码时,子线程比主执行时间长,因此输出不可见,也不会打印正确的值,因为它会提前终止
代码如下:
public static void main(String[] args) throws CorruptIndexException, IOException, LangDetectException, InterruptedException {
/* Initialization */
long startingTime = System.currentTimeMillis();
Indexer main = new Indexer(); // this class extends Thread
File file = new File(SITES_PATH);
main.addFiles(file);
/* Multithreading through ExecutorService */
ExecutorService es = Executors.newFixedThreadPool(4);
for (File f : main.queue) {
Indexer ind = new Indexer(main.writer, main.identificatore, f);
ind.join();
es.submit(ind);
}
es.shutdown();
/* log creation - code I want to execute when all the threads execution ended */
long executionTime = System.currentTimeMillis()-startingTime;
long minutes = TimeUnit.MILLISECONDS.toMinutes(executionTime);
long seconds = TimeUnit.MILLISECONDS.toSeconds(executionTime)%60;
String fileSize = sizeConversion(FileUtils.sizeOf(file));
Object[] array = {fileSize,minutes,seconds};
logger.info("{} indexed in {} minutes and {} seconds.",array);
}
我尝试了几种解决方案,如join()、wait()和notifyAll(),但都不起作用
我在stackoverflow上发现了这个Q&A,它处理了我的问题,但是join()被忽略,如果我
es.awaitTermination(timeout, TimeUnit.SECONDS);
实际上,executor服务从不执行线程
哪种解决方案可以只在ExecutorService块中执行多线程,并在最后完成主执行
# 1 楼答案
ExecutorService#submit()
方法返回一个Future
对象,可用于等待提交的任务完成想法是收集所有这些
Future
,然后对每个get()
进行调用。这可以确保在主线程继续之前,所有提交的任务都已完成比如:
# 2 楼答案
考虑到您的用户情况,您最好使用
invokeAll
方法。从Javadoc:使用:
这将执行所有提供的任务,并等待它们完成处理,然后再继续主线程。你需要调整代码以满足你的特殊需求,但你得到了要点。请注意,
invokeAll
方法的一个变体接受超时参数。如果您想在继续之前等待最长时间,请使用该变体。并确保在invokeAll
完成后检查收集的结果,以验证已完成任务的状态祝你好运