Good day! There is an Android application that actively uses asynchronous tasks. Suppose these tasks are 800 pieces and need to be performed asynchronously. You can simply take and run them all together and wait until they all are executed. But the problem is that RejectedExecution falling out, as far as I understand, due to the fact that the limit number of simultaneously acting threads in the pool is exceeded (800 simultaneous flows is obviously a bit too much). This suggests a solution: run them in "bundles" for example, 10 pieces each. If one task has completed, run another, and so on until all are completed. But how to implement it? How to make so that the number of simultaneously running AsyncTask was not more than 10 and at the same time after the end of each task a new one was started? Or maybe there are already some ready-made ways to plan for the implementation of too many simultaneous tasks and there is no need to reinvent the wheel? Thank you in advance!
- What data do you ship? Is it possible to do less? And you immediately need to display them one by one? - iamtihonov
- do less. Data are files downloaded from the network. - JuniorThree
- and you need to immediately display it, immediately after downloading? - iamtihonov
- I do not understand what it means to immediately display after downloading. Show where and how? And what does this have to do with planning these tasks? - JuniorThree
- Large, if you just need to upload files, this is a completely different task and you do not need AsynkTask, it is designed to be loaded after the data is displayed. - iamtihonov
2 answers
Use the Executors class and in it the static method newFixedThreadPool(n) , which will return an instance of ExecutorService . This design will help to organize a queue of threads of n simultaneously launched, the rest will be in the queue. Good example here . UPD Example, uses a queue of 200 threads, of which only two are simultaneously executed:
void test() { ExecutorService executorService = Executors.newFixedThreadPool(2); for (int i = 0; i < 200; i++) { executorService.submit(getRunnable(i)); } } Runnable getRunnable(final int i) { return new Runnable() { @Override public void run() { Log.i("test2", "начало "+i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } Log.i("test2", "конец " + i); } }; } - but no more than 128, including all. Obviously, your answer will not help in resolving the issue. - pavlofff
- @pavlofff as an option, you can move away from AsyncTask, and just work with Executors - Werder
The best solution is to rewrite the code, because if the user exits the application, you will not receive the downloaded files, the onPostExecute() method will not work. A bunch of IntentService and ExecutorService would be better. Then you will in any case receive the downloaded files and be able to save them. ExecutorService will assume the responsibility of restricting threads.
- rewriting code is not an option. If the user exits the application, then not receiving files will be the normal expected result, this is not a problem. Interested in a solution in the framework of AsyncTask - JuniorThree