Java主类在线程执行之前结束
我有一个多线程执行,我想跟踪并打印执行时间,但当我执行代码时,子线程比主执行时间长,因此输出不可见,也不会打印正确的值,因为它会提前终止 代码如下:Java主类在线程执行之前结束,java,multithreading,Java,Multithreading,我有一个多线程执行,我想跟踪并打印执行时间,但当我执行代码时,子线程比主执行时间长,因此输出不可见,也不会打印正确的值,因为它会提前终止 代码如下: public static void main(String[] args) throws CorruptIndexException, IOException, LangDetectException, InterruptedException { /* Initialization */ long startingTime =
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上发现了这一点,它解决了我的问题,但是join()被忽略,如果我
等待终止(超时,时间单位为秒)
实际上,executor服务从不执行线程
哪个解决方案可以仅在ExecutorService块中执行多线程,并在最后以主执行结束?方法返回一个未来的对象,该对象可用于等待提交的任务完成
其思想是收集所有这些Future
s,然后对它们中的每一个调用get()
。这确保在主线程继续之前,所有提交的任务都已完成
大概是这样的:
ExecutorService es = Executors.newFixedThreadPool(4);
List<Future<?>> futures = new ArrayList<Future<?>>();
for (File f : main.queue) {
Indexer ind = new Indexer(main.writer, main.identificatore, f);
ind.join();
Future<?> future = es.submit(ind);
futures.add(future);
}
// wait for all tasks to complete
for (Future<?> f : futures) {
f.get();
}
// shutdown thread pool, carry on working in main thread...
Executors服务=Executors.newFixedThreadPool(4);
列表>();
for(文件f:main.queue){
索引器ind=新索引器(main.writer,main.identificatore,f);
ind.join();
未来=提交(ind);
期货。添加(期货);
}
//等待所有任务完成
for(未来f:未来){
f、 get();
}
//关闭线程池,在主线程中继续工作。。。
根据您的用户情况,您最好使用invokeAll
方法。从Javadoc:
执行给定的任务,返回保存任务的未来列表
全部完成时的状态和结果。Future.isDone()对于每个
返回的列表的元素。请注意,已完成的任务可能
正常终止或通过引发异常终止。结果
如果给定集合在
此操作正在进行中
使用:
final Collection<Indexer> tasks = new ArrayList<Indexer>();
for(final File f: main.queue) {
tasks.add(new Indexer(main.writer, main.identificatore, f));
}
final ExecutorService es = Executors.newFixedThreadPool(4);
final List<Future<Object>> results = es.invokeAll(tasks);
final Collection tasks=new ArrayList();
for(最终文件f:main.queue){
添加(新索引器(main.writer,main.identificatore,f));
}
final Executors服务es=Executors.newFixedThreadPool(4);
最终列表结果=es.invokeAll(任务);
这将执行所有提供的任务,并等待它们完成处理,然后再继续主线程。您需要调整代码以满足您的特殊需要,但您得到了要点。请注意,invokeAll
方法的一个变体接受超时参数。如果要在继续之前等待最长时间,请使用该变量。并确保在invokeAll
完成后检查收集的结果,以验证已完成任务的状态
祝你好运。我只需将Runnable
提交给ExecutorService
,而不调用join()
或其他任何东西。您使用并发框架的方式似乎不正确。还要注意生成的线程是用户线程:守护进程线程不会阻止JVM退出。但是,我非常确定默认情况下线程是用户线程。