Creating too many threads in Java
I use threads in my java application to get data in parallel (using network calls) I have a method (not in the thread class) that creates a thread pool of a given size (up to 10-15) and uses them for network calls. I call this method multiple times from the loop
When I run this application on a slow machine (3 GB ram, Pentium IV), everything is normal, but when I run it on IMAC (32 GB ram, i7 processor), it creates too many threads, about 2500, and sometimes throws an out of memory error
I suspect that the JVM will not put the completed thread back into the pool after completion, so it is creating a new thread
Even on iMac, if I keep thread sleep(1000); In the for loop I mentioned above, everything is normal Although about 900 threads were created
The following is a code example for this application:
public ArrayList<String> getValuesForKeyFromMaps(String key,ArrayList<Meta> locations) throws InterruptedException,ExecutionException { int threadNum = locations.size(); // 10-15 at max ExecutorService executor = Executors.newFixedThreadPool(threadNum); List<FutureTask<ArrayList<String>>> taskList = new ArrayList<FutureTask<ArrayList<String>>>(); for(final Meta location : locations){ FutureTask<ArrayList<String>> futureTask_1 = new FutureTask<ArrayList<String>>(new Callable<ArrayList<String>>() { public ArrayList<String> call() throws Exception { // Service call return getValues(key,location); } }); taskList.add(futureTask_1); executor.execute(futureTask_1); } ArrayList<String> values = new ArrayList<String>(); // Wait until all results are available and combine them at the same time for (int j = 0; j < threadNum; j++) { FutureTask<ArrayList<String>> futureTask = taskList.get(j); values.addAll(futureTask.get()); } executor.shutdown(); return values; }
If I call the above method with the following for loop on iMac, it will throw a memory error because it creates about 2500 threads But it works well on slower machines
for(String key : keySet){ getValuesForKeyFromMaps(key,MetaMap.get(key)); }
Also, using the following code, it works normally on iMac, with about 900 threads
for(String key : keySet) { getValuesForKeyFromMaps(key,MetaMap.get(key)); Thread.sleep(200); // Sleeping for 200 ms }
If I increase the sleep time in the above for loop to 1000 milliseconds, it only creates 30-50 threads and the application works normally
How do I control the maximum number of threads allowed in an application? I intend to create / use up to 10-15 threads at a given time, but Java creates too many
Solution
Creating too many threads is not Java; You are?
Do not create an executor every time you call a function If you have 100 collections and each collection contains 100 elements, you will create 10000 threads - which is very resource consuming... And meaningless
ExecutorService executor = Executors.newFixedThreadPool(threadNum);
You are most likely to have eight kernels - just create an executor with eight threads and use it anywhere Your code will run faster and your application will consume less and less resources
Be familiar with the code review singleton executor problem You can use this solution in your application