MultiThread and Processor's Capacity

116 views Asked by At

I dont understand why I have 4 Threads RUNNING but only 50% of processor's capacity used : indeed that's mean only 2/4 processors are used.

enter image description here

EDIT : I think this is due to the limit : my mistake is 5 Threads are RUNNING at the same time so by default the System limit the %CPU to 2 cores (50%). I am going to check about 4 Threads

2

There are 2 answers

1
GhostCat On

This very much depends on what your threads are doing.

If the work they are doing is heavily focused on IO operations, then your CPUs can run many many such threads - without getting to any significant CPU load ever.

In other words: most likely, your threads are not doing CPU intensive work.

But we can't know for sure, as you are not giving any hints about the nature of your application.

1
Krzysztof Cichocki On

First, it depends on how many CPU cores do you have - if you have more CPU cores than running threads, then there aren't enough threads to keep all the cores in the processor busy at 100%.

Another thing is that a thread can be in a waiting state eg. waiting on monitor and in such case it doesn't consume the CPU cycles.

In your screenshot one of threads from your pool is in MONITOR state - it is not executing at that moment - it is waiting for something, and as such not consuming CPU cycles.

I think that all the threads in your pool are similar and all share the characteristic of having some potential wait on a monitor - and this limits the possibility of consuming all the CPU cores at 100%.

For example, this simple program should consume all of your cores at 100% simply because it doesn't have any waiting, but if you uncomment the line that orders it to sleep 1 nanosecond Thread.sleep(0, 1); then you will hardly notice any cpu load.

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class consumeMaxOfCPU {

    public static void main(String[] args) {
        int availableProcessors = Runtime.getRuntime().availableProcessors();
        // availableProcessors = availableProcessors /2; // uncomment this line to see around half of the load - because there will be less threads than CPU cores.
        ExecutorService pool = Executors.newFixedThreadPool(availableProcessors);
        for (int n = 0; n < availableProcessors; n++) {
            pool.submit(new HeavyTask(n));
        }
    }

    private static class HeavyTask implements Callable<Long> {
        private long n;

        public HeavyTask(long n) {
            this.n = n;
        }

        @Override
        public Long call() throws Exception {
            // there are very little chances that this will finish quickly :)
            while (n != -10) {
                n = n * n;
                //  Thread.sleep(0, 1); // uncomment this line to see almost no load because of this sleep.
            }
            return n;
        }
    }
}