1

I've read, for example in Java Concurrency in Practice, that "a program with only one thread can run on at most one processor at a time."

However, if I run a single-threaded java class on my 2.5 GHz Intel Core 2 Duo Macbook Pro, I can see (in Activity Monitor) that the CPU usage shoots up from near 0 to around 60% on BOTH cores.

Is the mac OS somehow switching my thread from one core to another, and if so, why?

Thanks! Here's the code..

public class PrimeCalculator {

    public static void findPrimes (int start, int end){
        int countPrimes = 0;
        for (int i=start; i<end; i++){
            if (i % 1000000 == 0){
                System.out.println("Did a million..");
            }
            boolean found = true;
            for (int check = 2; check <= Math.sqrt(i); check++){
                if (i % check == 0){
                    found = false;
                    break;
                }
            }
            if (found == true){
                //System.out.println(i);
                countPrimes++;
            }
        }
        System.out.println("I counted "+countPrimes+" primes");
    }

    public static void main(String[] args){
        findPrimes(0,100000000);
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
Bruce
  • 2,406
  • 5
  • 29
  • 35
  • 1
    I would optimise `Math.sqrt(i)` to save it running on every iteration. It is more likely that the thread is switching between cores (using 50% or each) and there is a little extra work on the machine bringing it up to 60% – Peter Lawrey Apr 14 '13 at 08:42
  • Thanks for your comment, Peter. My question is more basic than your comment gives me credit for. I'm really just asking why doesn't the mac run this thread on one core? (The program is just a demo to show that it's getting split across two) If it's really able to spread the load across two, then why do concurrency books say you need multiple threads to spread processing load? – Bruce Apr 14 '13 at 08:46
  • 1
    It runs 100% on one core and then 100% on another core averaging 50% on each. (60% with some overhead) To use both cores at the same time and not just over time, you need multiple threads. – Peter Lawrey Apr 14 '13 at 08:49
  • 1
    Thanks, Peter. I just read your answer to a similar question here http://stackoverflow.com/questions/8485947/why-does-a-single-threaded-process-execute-on-several-processors-cores which I think is the piece I was missing. Thank you for your informative answers! – Bruce Apr 14 '13 at 08:51
  • Thank you. In a 2.5 GHz processor it can perform in the order of 2.5 billion instructions per second. On the other hand you can't see a movie changing from one frame to the next, even though it does this only 42 times per second (about 50 million clock cycles). This means the computer can do a lot of things so fast you can't tell the difference. The best route is to measure the difference it makes if you use multiple threads. BTW don't assume it will improve performance, the overhead can make it much slower if you are not careful. – Peter Lawrey Apr 14 '13 at 08:57
  • Use `/Developer/Applications/Instruments.app` to se more detail. – trashgod Apr 14 '13 at 09:00

2 Answers2

2

A Java thread may be mapped one-to-one to a kernel thread, b ut it doesn't have to be the case. Your OS is free to swap the thread from one core to another for no reason. Also the JVM can use multiple cores, even if you use only one thread.

Maybe you can find some more informations here: Why does a single threaded process execute on several processors/cores?

Community
  • 1
  • 1
Martin Seeler
  • 6,874
  • 3
  • 33
  • 45
1

You can use jstack command to see the thread behavior. Don't forget that Java also creates many threads in background - prime example being the GC thread, finalizer, signal dispatcher, etc..

On my Mac it is showing around 8 threads - your mileage may vary. The OS and JDK implementation are free to schedule the threads as and where they want!

Akhilesh Singh
  • 2,548
  • 1
  • 13
  • 10