2

Iam using below code for uploading images on the remote server.When I use below it is uploading all images cocurrently on remote server.

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

Whenever i used below code

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

adds all the future objects to futurelist immediately returning from runnable(not waiting in runnable until completion of uploading of all images(background uploading processing is going)

But whenever i uncommented below line in above code ,after successful uploading of every image it returns from runnable.

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

is there anything wrong in my code and is it ok to take remote server connection more at a time or any load is on server?How to upload the images by using cocurrent programming java?Please give us guidance?

Do the submit() and execute() functions have the same effect?

andersoj
  • 22,406
  • 7
  • 62
  • 73
ADIT
  • 2,388
  • 9
  • 34
  • 46

2 Answers2

3

When you call singleFuture.get() you are waiting for the operation to complete. So the loop won't continue to execute next statement until this one returns a result.

You need to submit your tasks in the first loop and after that, another loop should iterate over the results future.get() on your list to make it async

From @andersoj's answer;

The Pool size should be something related to your CPU cores. Not the number of images you have in hand. Say if you have 2 cored CPU, a coefficient of 5 (just my guess of coefficient) for image uploading io time.

POOL_SIZE = NUM_OF_CPU_CORE*coeffiecient;

fmucar
  • 14,361
  • 2
  • 45
  • 50
2

submit() adds a task to the queue and returns a Future. execute() does not return a Future. See also here. Different orderings you observe may occur as side-effects of the additional management that happens inside submit() and probably are irrelevant. (But see @fmucar's answer...)

Not sure precisely what your question is...

It doesn't really make sense to size your thread pool based on the number of images you want to upload -- probably some small number of threads is sufficient, since you're just trying to keep some TCP streams fed. One thread per image, if the list of images is large, won't buy you anything.

If you are collecting Futures only to know when the uploads complete, consider one of the following:

Edited to add: Good catch, @fmucar, the call to .get() in the logger line forces sequentiality, so the thread pool is a waste.

invokeAll() example

Here's an attempt to give you an invokeAll() example; not sure if it quite matches your code.

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.    
Community
  • 1
  • 1
andersoj
  • 22,406
  • 7
  • 62
  • 73
  • Can you elaborate , which method(submit()/execute()) is opt for uploading images on remote service(server)? Or any concept is for large size of images uploading on to the remote server? – ADIT Feb 25 '11 at 10:24
  • The two should be logically equivalent for your purpose; the only deciding factors are whether you want to use `Callable`s and/or `Future`s. If you don't care (i.e., `Runnable`s work fine and you don't need a future completion handle) then there's not real difference. – andersoj Feb 25 '11 at 10:30
  • @andersoj:Thanks for giving suggestion.But you suggested to use invokeall() and completeservice().Can i use one or both?Please give me any link for sample code? – ADIT Feb 25 '11 at 10:46
  • 1
    @ADIT: Use either `invokeAll()` OR `CompletionService`; probably not both. The former is very, very simple and effective. The latter is more flexible and more complicated. For your purpose, I recommend the former so long as this "image upload" is not being kicked off from a UI thread or similar -- the effect of `invokeAll()` is to *block* the current thread until all the subsidiary tasks complete. Very useful in some circumstances. If this is in a UI thread or anything else that has more business to do, then you'll want a `CompletionService`. – andersoj Feb 25 '11 at 11:33
  • 1
    @ADIT: For examples, see e.g., http://stackoverflow.com/questions/5013999/how-can-i-implement-or-find-the-equivalent-of-a-thread-safe-completionservice and http://stackoverflow.com/questions/4912228/when-should-i-use-a-completionservice-over-an-executorservice which have snippets. For `invokeAll()` it's pretty simple but see my post: http://stackoverflow.com/questions/4470492/java-executor-service-sequential-execution/4470530#4470530 . If you can give a bit more example code from your app, I might be able to provide a full example for you (but tell me which you want to see.) – andersoj Feb 25 '11 at 11:35
  • @fmucar: SO is great -- wish there was a better way to incentivize aggregation of good answers, because it's common that folks pick up on different aspects of questions... – andersoj Feb 25 '11 at 11:37
  • @andersoj, absolutely agree on that. – fmucar Feb 25 '11 at 11:52