首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用java并发编程的ExecutorService?

如何使用java并发编程的ExecutorService?
EN

Stack Overflow用户
提问于 2011-02-25 18:09:24
回答 2查看 6.9K关注 0票数 2

我使用下面的代码将图像上传到我在下面使用的远程server.When,它是同时在远程服务器上上传所有图像。

代码语言:javascript
复制
List<Future<String>> futureList = new ArrayList<Future<String>>();
ExecutorService execService = Executors.newFixedThreadPool(Images.size());
for (IImage image : Images) { 
  try {
    //execService.execute(lServerRequest.new uploadImages(image.getDataPath(),image.getDisplayName()));
    singleFuture = execService.submit(lServerRequest.new uploadImages(image.getDataPath(),image.getDisplayName()));
    //Log.d("","singleFuture -------"+singleFuture.get());
    futureList.add(singleFuture);
    Log.d("","futureList Size:"+futureList.size());
  } catch(Exception e){
    execService.shutdown();
  }

每当我使用下面的代码时

代码语言:javascript
复制
   singleFuture = execService.submit(lServerRequest.new uploadImages(image.getDataPath(),image.getDisplayName()));
//Log.d("","singleFuture -------"+singleFuture.get());
    futureList.add(singleFuture);

将所有未来的对象添加到立即从runnable返回的futurelist中(不在runnable中等待,直到所有图片上传完成(后台上传处理正在进行))

但每当我在上面的代码中取消注释下面的代码行时,在成功上传每个图像后,它都会从runnable返回。

代码语言:javascript
复制
singleFuture = execService.submit(lServerRequest.new uploadImages(image.getDataPath(),image.getDisplayName()));
Log.d("","singleFuture -------"+singleFuture.get());
futureList.add(singleFuture);

我的代码有没有问题,是否可以一次多做远程服务器连接,或者任何负载都在服务器上?如何使用并发编程java上传图片?请指导我们?

submit()execute()函数是否具有相同的效果?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-02-25 18:32:05

当您调用singleFuture.get()时,您正在等待操作完成。所以循环不会继续执行next语句,直到这个语句返回结果。

您需要在第一个循环中提交任务,然后,另一个循环将遍历列表上的结果future.get(),使其成为异步的

来自@andersoj的答案;

池大小应该与您的CPU核心相关。而不是你手中的图像数量。比方说,如果你有2核CPU,那么图像上传的系数是5(我猜测的系数)。

POOL_SIZE = NUM_OF_CPU_CORE*coeffiecient;

票数 3
EN

Stack Overflow用户

发布于 2011-02-25 18:18:53

submit()向队列中添加一个任务并返回一个Futureexecute()不返回Future。另请参见here。您观察到的不同顺序可能会作为submit()中发生的额外管理的副作用出现,并且可能是无关的。(但请参阅@fmucar的答案...)

不确定你的问题是什么.

根据要上传的图像的数量来调整线程池的大小并不是很有意义--可能只有少量的线程就足够了,因为您只是想保持一些TCP流的供给。每张图片一个线程,如果图片列表很大,不会给你带来任何好处。

如果您收集Futures时只知道上传完成的时间,请考虑以下其中一种情况:

请参阅my answer here for more details)

  • Use a CompletionService

(请参见a

  • )使用invokeAll(),它将一直阻塞,直到所有提交的任务完成为止

编辑以添加:Good catch,@fmucar,在日志记录器行中对.get()的调用强制顺序,因此线程池是一种浪费。

invokeAll()示例

这里尝试给出一个invokeAll()示例;不确定它是否与您的代码完全匹配。

代码语言:javascript
复制
final int poolSize = ...;  // see fmucar's answer
final ExecutorService execService = Executors.newFixedThreadPool(poolSize);
final List<Callable<>> uploadTasks = new ArrayList<Callable<>>();

for (final IImage image : Images) { 
   // maybe I got this wrong?  Can't quite parse your code.
   Callable<String> uTask = new uploadImages(image.getDataPath(),image.getDisplayName());
   uploadTasks.add(uTask);
}
// this thread will block here until all the tasks complete
final List<Future<String>> futureList = execService.invokeAll();
// or you can toss the result entirely if the futures don't matter.    
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5115940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档