Guru
Guru

Reputation: 302

Why is the total runtime slower when more threads were created as compared to lesser number of threads

I am playing around multithreading to understand it properly. So I was trying to test how "number of threads being created" can impact the total runtime of a given task.

class Worker implements Runnable {

    private int id;

    public Worker(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        System.out.println("Starting thread ->" + Thread.currentThread().getName() + " with ID: " + id);
        System.out.println("Finishing thread ->" + Thread.currentThread().getName() + " with ID: " + id);
    }
}

public class App {

    public static void main(String[] args) throws InterruptedException {
        App app = new App();
        ExecutorService threadPool;
        Map<Integer, Long> performanceMetric = new HashMap<>();
        for (int j = 3; j > 0; j -= 1) {
            long begin = System.currentTimeMillis();

So here I am creating highest number of threads by assigning a high value on the loop. Am simply using the value of "j" from the loop and assigning it to the Executor.

            threadPool = Executors.newFixedThreadPool(j);
            System.out.println("\nTotal threads created: " + j);
            app.performService(threadPool);
            threadPool.shutdown();

Ensuring that the executor (threadpool) is shutdown first before calculating the total time taken.

            threadPool.awaitTermination(1, TimeUnit.SECONDS);

Here am calculating the total time taken for completing the task. The total time wont be calculated unless all the tasks are complete.

            long totalTime = (System.currentTimeMillis() - begin);
            System.out.println("Is the ThreadPool shutdown: " + (threadPool.isTerminated() ? "Yes" : "No"));
            performanceMetric.put(j, totalTime);
            System.out.println("\nTotal time elapsed when using " + j + " threads is " + totalTime + " milliseconds");
        }
        Set<Integer> keySet = performanceMetric.keySet();
        for (int key : keySet) {
            System.out.println("\nSUMMARY\n\nTotal time elapsed when using " + key + " threads is "
                    + performanceMetric.get(key) + " milliseconds");
        }
    }

    public void performService(ExecutorService threadPool) {
        for (int i = 0; i < 5; i++) {
            threadPool.submit(new Worker(i));
        }
    }
}

The output for the above program is below

Begin output

Total threads created: 3
Starting thread ---pool-1-thread-1 with ID: 0
Starting thread ---pool-1-thread-3 with ID: 2
Starting thread ---pool-1-thread-2 with ID: 1
Finishing thread ---pool-1-thread-3 with ID: 2
Finishing thread ---pool-1-thread-1 with ID: 0
Finishing thread ---pool-1-thread-2 with ID: 1
Starting thread ---pool-1-thread-3 with ID: 3
Starting thread ---pool-1-thread-2 with ID: 4
Finishing thread ---pool-1-thread-3 with ID: 3
Finishing thread ---pool-1-thread-2 with ID: 4
Is the ThreadPool shutdown: Yes

Total time elapsed when using 3 threads is 4 milliseconds

Total threads created: 2
Starting thread ---pool-2-thread-1 with ID: 0
Finishing thread ---pool-2-thread-1 with ID: 0
Starting thread ---pool-2-thread-1 with ID: 2
Finishing thread ---pool-2-thread-1 with ID: 2
Starting thread ---pool-2-thread-2 with ID: 1
Finishing thread ---pool-2-thread-2 with ID: 1
Starting thread ---pool-2-thread-1 with ID: 3
Finishing thread ---pool-2-thread-1 with ID: 3
Starting thread ---pool-2-thread-2 with ID: 4
Finishing thread ---pool-2-thread-2 with ID: 4
Is the ThreadPool shutdown: Yes

Total time elapsed when using 2 threads is 0 milliseconds

Total threads created: 1
Starting thread ---pool-3-thread-1 with ID: 0
Finishing thread ---pool-3-thread-1 with ID: 0
Starting thread ---pool-3-thread-1 with ID: 1
Finishing thread ---pool-3-thread-1 with ID: 1
Starting thread ---pool-3-thread-1 with ID: 2
Finishing thread ---pool-3-thread-1 with ID: 2
Starting thread ---pool-3-thread-1 with ID: 3
Finishing thread ---pool-3-thread-1 with ID: 3
Starting thread ---pool-3-thread-1 with ID: 4
Finishing thread ---pool-3-thread-1 with ID: 4
Is the ThreadPool shutdown: Yes

Total time elapsed when using 1 threads is 0 milliseconds

Total time elapsed when using 1 threads is 0 milliseconds

Total time elapsed when using 2 threads is 0 milliseconds

Total time elapsed when using 3 threads is 4 milliseconds

end output

I am surprised how one or two threads performed faster compared to three threads. Can someone please explain.

Upvotes: 0

Views: 35

Answers (1)

erickson
erickson

Reputation: 269687

You aren't doing a constant amount of work in each trial, divided by a varying number of threads. You are simply creating a varying number of threads. The more threads you have to create, start, and monitor, the longer it will take.

That's your multi-threading overhead; it's only worthwhile when your work load will benefit from parallelization. In this example, it doesn't.

Upvotes: 1

Related Questions