Skip to content
Advertisement

Why does Thread.activeCount() count more threads than my code creates?

I’m a beginner in Java development and i trying to write a multi threading process with using CountDownLatch in below code. But ExecutorService not working as it should.

ExecutorService thread number not working as it defined in code.

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class HTTPrequester {
    
    private ExecutorService exs;
    private CountDownLatch latch;
    private int thread_num = 50;
    private String[] url_list;
    
    public static void main(String[] args) {
        HTTPrequester req = new HTTPrequester();
        req.action();
    }
    
    
    public void action() {
        url_list = new String[]{"https://google.com/","https://microsoft.com/","https://yahoo.com/","https://stackoverflow.com/","https://youtube.com/","https://google.com/","https://microsoft.com/","https://yahoo.com/","https://stackoverflow.com/","https://youtube.com/",
                "https://google.com/","https://microsoft.com/","https://yahoo.com/","https://stackoverflow.com/","https://youtube.com/","https://google.com/","https://microsoft.com/","https://yahoo.com/","https://stackoverflow.com/","https://youtube.com/"};
        exs = Executors.newFixedThreadPool(thread_num);
        latch = new CountDownLatch(url_list.length);
        
        for(String url: url_list) {
            exs.submit(new Runner(latch,url));
        }
        
    }
    public class Runner implements Runnable {
        
        private CountDownLatch latch;
        private String url;
        public Runner(CountDownLatch latch, String url) {
            this.latch = latch;
            this.url = url;
        }

        @Override
        public void run() {
            try {
                HttpClient client = HttpClient.newHttpClient();
                HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).build();
                HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
                System.out.println("Thread Count: "+Thread.activeCount()+" - Latch Count: "+latch.getCount());
            }catch(Exception e) {}
            latch.countDown();
        }
        
    }
    
}

Console log;

Thread Count: 81 - Latch Count: 20
Thread Count: 81 - Latch Count: 20
Thread Count: 81 - Latch Count: 20
Thread Count: 81 - Latch Count: 17
Thread Count: 81 - Latch Count: 16
Thread Count: 81 - Latch Count: 15
Thread Count: 81 - Latch Count: 14
Thread Count: 81 - Latch Count: 13
Thread Count: 81 - Latch Count: 12
Thread Count: 81 - Latch Count: 11
Thread Count: 81 - Latch Count: 10
Thread Count: 81 - Latch Count: 9
Thread Count: 81 - Latch Count: 8
Thread Count: 81 - Latch Count: 7
Thread Count: 81 - Latch Count: 6
Thread Count: 81 - Latch Count: 5
Thread Count: 81 - Latch Count: 4
Thread Count: 81 - Latch Count: 3
Thread Count: 81 - Latch Count: 2
Thread Count: 81 - Latch Count: 1

I defined thread number as 50, but when it works Thread.activeCount() function returns 81. Why ?

Advertisement

Answer

You are using Thread.activeCount() which returns (an estimate of) the number of threads in the caller thread’s ThreadGroup.

This is not the same as querying how many thread is using your fixed size thread pool (you know the answer already, since you’ve created it).

As the others have said, you’re not the only creating threads, specifically, you’re not the only one creating threads in what is (I’m guessing) the ThreadGroup of your main Thread.

The executor you’ve created will create threads that are beloging to the ThreadGroup of the thread where you are actually instantiating it, so you will always have a higher count than your thread pool size.

If you want to see (for educational and debugging purposes) the complete picture of all threads in your jvm and what they’re doing (i.e. their stacktrace), try using jstack (it should be bundled in your JDK of choice).

https://docs.oracle.com/en/java/javase/11/tools/jstack.html

Advertisement