2

我正在使用下面的代码在远程服务器上上传图像。当我在下面使用它时,它会将所有图像同时上传到远程服务器上。

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();
  }

每当我使用下面的代码时

   singleFuture = execService.submit(lServerRequest.new uploadImages(image.getDataPath(),image.getDisplayName()));
//Log.d("","singleFuture -------"+singleFuture.get());
    futureList.add(singleFuture);

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

但是,每当我在上面的代码中取消注释时,在成功上传每张图片后,它都会从可运行文件返回。

singleFuture = execService.submit(lServerRequest.new uploadImages(image.getDataPath(),image.getDisplayName()));
Log.d("","singleFuture -------"+singleFuture.get());
futureList.add(singleFuture);

我的代码有什么问题吗?一次可以进行更多的远程服务器连接还是服务器上有任何负载?如何使用并发编程java上传图像?请给我们指导?

submit()和功能是否execute()具有相同的效果?

4

2 回答 2

3

当您打电话时, singleFuture.get()您正在等待操作完成。所以循环不会继续执行下一条语句,直到这条语句返回结果。

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

来自@andersoj 的回答;

池大小应该与您的 CPU 内核有关。不是您手头的图像数量。假设您有 2 个核心 CPU,则图像上传 io 时间的系数为 5(只是我对系数的猜测)。

POOL_SIZE = NUM​​_OF_CPU_CORE*系数;

于 2011-02-25T10:32:04.673 回答
2

submit()将任务添加到队列并返回一个Future. execute()不返回Future. 另请参见此处。您观察到的不同排序可能是内部发生的额外管理的副作用,submit()并且可能无关紧要。(但请参阅@fmucar 的回答......)

不确定你的问题是什么......

根据您要上传的图像数量来确定线程池的大小并没有什么意义——可能少量线程就足够了,因为您只是试图保持一些 TCP 流的馈送。每个图像一个线程,如果图像列表很大,不会给你买任何东西。

如果您收集Futures只是为了知道上传何时完成,请考虑以下其中一项:

编辑添加:很好的捕获,@fmucar,.get()在记录器行中的调用强制顺序,所以线程池是一种浪费。

调用所有()示例

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

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.    
于 2011-02-25T10:18:53.177 回答