我有方法
CoInitialize/CoUninitialize
作为单个线程运行。我希望使用public List<SenderResponse> sendAllFiles(String folderName) {
List<File> allFiles = getListOfFiles();
List<SenderResponse> finalResponse = new ArrayList<SenderResponse>();
for (File file : allFiles) {
finalResponse.getResults().add(sendSingleFile(file));
}
return finalResponse;
}
运行sendSingleFile(file)
,这样我就可以减少发送文件所需的总时间。
如何使用multithread
为各种文件运行sendSingleFile(file)
并获得最终回复?
我发现使用multithread
的文章很少。但是如何处理threadpoolexecutor
期间收到的响应并将其添加到最终sendSingleFile(file)
?
我对多线程有点新意。请建议处理这些文件的最佳方法。
答案 0 :(得分:1)
定义执行者服务
ExecutorService executor = Executors.newFixedThreadPool(MAX_THREAD); //Define integer value of MAX_THREAD
然后,对于每项工作,您可以执行以下操作: -
Callable<SenderResponse> task = () -> {
try {
return sendSingleFile(file);
}
catch (InterruptedException e) {
throw new IllegalStateException("Interrupted", e);
}
};
Future<SenderResponse> future = executor.submit(task);
future.get(MAX_TIME_TO_WAIT, TimeUnit.SECONDS); //Blocking call. MAX_TIME_TO_WAIT is max time future will wait for the process to execute.
答案 1 :(得分:0)
您开始,编写适用于单线程解决方案的代码。您发布的代码甚至不会编译;方法签名表示返回SenderResponse
;而你在方法中使用/返回List<SenderResponse>
!
当这些东西有效时,你继续这样做:
要注意的一点是:确保add()
以某种方式同步 - 让多个线程更新普通的ArrayList是不安全的。
答案 2 :(得分:0)
根据您的情况,我会使用工作窃取池(ForkJoin执行器服务)并向其提交“作业”。如果您正在使用guava,可以将其包装在listeningDecorator
中,这样您就可以在它返回的期货上添加一个监听器。
示例:
// create the executor service
ListeningExecutorService exec = MoreExecutors.listeningDecorator(Executors.newWorkStealingPool());
for(Foo foo : bar) {
// submit can accept Runnable or Callable<T>
final ListenableFuture<T> future = exec.submit(() -> doSomethingWith(foo));
// Run something when it is complete.
future.addListener(() -> doSomeStuff(future), exec);
}
请注意,无论未来是否成功,都会调用侦听器。