How to use ExecutorService for Java programming at the same time?

Iam using the code below to upload images to a remote server. When I use below, it uploads all the images at once to the 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 future objects to the future list, immediately returning from runnable (without waiting in runnable until all images have finished loading (background loading processing is performed)

But whenever I uncomment below the line above the code, after successfully loading each 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 something wrong in my code, and is it normal to accept a remote connection to the server more at a time or any download on the server? How to load images using java parallel programming? Please give us a guide?

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

+2
source share
2 answers

When you call singleFuture.get() , you are waiting for the operation to complete. Thus, the loop will not continue to execute the next statement until it returns the result.

You need to send your tasks to the first loop, and then, the next loop should future.get() over the results of future.get() in your list to make it asynchronous

From the answer by @andersoj;

The pool size must be something related to your processor cores. Not the number of images you have. Say, if you have 2 core processors, the coefficient is 5 (just my guess of the coefficient) for loading the image and time.

POOL_SIZE = NUM_OF_CPU_CORE * coeffiecient;

+3
source

submit() adds the task to the queue and returns Future . execute() does not return Future . See also here . Various observable orders can occur as side effects of additional control that occur inside submit() and probably don't matter. (But see @fmucar's answer ...)

Not sure exactly what your question is ...

Actually, it doesn't make sense to determine the size of the thread pool based on the number of images you want to upload - probably a small number of threads is enough, because you are just trying to save some streams of TCP streams. One stream per image, if the list of images is large, will not buy you anything.

If you are building Futures just to find out when the download is complete, consider one of the following:

Edited to add . A good catch, @fmucar, calling .get() on a log line leads to a sequence, so the thread pool is waste.

invokeAll () example

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

 final int poolSize = ...; // see fmucar 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
source

Source: https://habr.com/ru/post/1346161/


All Articles