481

How can I find the number of cores available to my application from within Java code?

charleslparker
  • 1,904
  • 1
  • 21
  • 31
Damir
  • 54,277
  • 94
  • 246
  • 365
  • 3
    For pretty much all intents and purpose "core == processor". – Joachim Sauer Jan 21 '11 at 13:59
  • 38
    finding the number of cores the machine has physically is hard using purely Java. Finding the number of cores the Java program can use at startup is easy, using *Runtime.getRuntime().availableProcessors()*. Due to the ability of all major modern OSes to set CPU affinity (i.e. restrict an application to only a certain number of cores) this is a concern to keep in mind. – SyntaxT3rr0r Jan 21 '11 at 16:15
  • 10
    Logical or physical cores? There's an important difference. – arkon Jul 29 '15 at 03:55
  • Also see: https://stackoverflow.com/questions/1980832/java-how-to-scale-threads-according-to-cpu-cores – Christophe Roussy Jul 04 '17 at 09:52

5 Answers5

871
int cores = Runtime.getRuntime().availableProcessors();

If cores is less than one, either your processor is about to die, or your JVM has a serious bug in it, or the universe is about to blow up.

darioo
  • 46,442
  • 10
  • 75
  • 103
  • No problem, since most of the information gathered from the `Runtime` class is a String, I thought it would be helpful to show this one returns an `int`. – Bart Kiers Jan 21 '11 at 14:23
  • 139
    This will give you the number of logical threads. e.g. If you have hyper-threading on, this will be double the number of cores. – Peter Lawrey Jan 21 '11 at 14:29
  • 7
    @Peter, yeah, good point. I felt myself King of the Hill when performing this action with my i7 machine! :) – Bart Kiers Jan 21 '11 at 14:39
  • 19
    @Peter Lawrey: it only gives the number of logical threads actually available to the JVM (at startup I guess). Using CPU affinity the user/OS can restrict the number of "cores" a JVM sees. You can even do it on a running JVM but I'm not too sure how this influence *availableProcessors()*. – SyntaxT3rr0r Jan 21 '11 at 16:17
  • 2
    @SyntaxT3rr0r I suspect availableProcessors doesn't change with the affinity. – Peter Lawrey Jan 21 '11 at 16:28
  • 31
    @PeterLawrey: that seems to be incorrect, the Java documentation for availableProcessors() says "This value may change during a particular invocation of the virtual machine. Applications that are sensitive to the number of available processors should therefore occasionally poll this property and adjust their resource usage appropriately." [source](http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#availableProcessors%28%29) – JW. Jun 16 '12 at 09:38
  • @JW You could be right, I have never seen someone change the number of virtual CPUs of a running production system before. ;) I tend to only work in real machines which don't change. – Peter Lawrey Jun 18 '12 at 08:39
  • 13
    @universe blowing up and such : or the machine actually has more than 2,147,483,647 logical threads available ? ;) – Pierre Henry Oct 22 '12 at 13:08
  • 5
    @PierreHenry Well, that would be the day that we could solve all NP problems in P time for N <= 2 147 483 647 :) – Cruncher Sep 13 '13 at 14:19
  • 3
    @PeterLawrey There are real machines with hot swappable CPUs. – noisesmith Sep 26 '13 at 00:18
  • 7
    @PeterLawrey, I can confirm that on Windows 7 SP1 x64 with Java 1.7.0_51, availableProcessors() does change with the affinity. You can easily test this by using jrunscript to call java.lang.Runtime.getRuntime().availableProcessors(), change the processor affinity of jrunscript.exe with Windows task manager, and then run availableProcessors() again, you will see the number will change. – Simon Kissane May 02 '14 at 05:33
  • 4
    @PeterLawrey Real machines can gain or lose CPUs as well. I've hot-swapped processors (and RAM) on high-end servers with my own two hands. – arkon Jul 29 '15 at 04:01
  • 2
    I have a lot of questions to all of you people running software straight on server hardware, rather than in a virtual machine. – Dragas Jul 11 '20 at 07:41
  • 2
    Upvoted for being useful as well as having a sense of humour – GideonleGrange Jul 29 '20 at 09:31
  • @Dragas I have allot of questions for all you people who can see into the future so clearly – dan carter Mar 10 '21 at 01:47
  • @dancarter even at the time it was the norm to use virtual machines to separate everything out. – Dragas Mar 10 '21 at 12:11
36

If you want to get number of physical cores you can run cmd and terminal command and then to parse the output to get info you need.Below is shown function that returns number of physical cores .

private int getNumberOfCPUCores() {
    OSValidator osValidator = new OSValidator();
    String command = "";
    if(osValidator.isMac()){
        command = "sysctl -n machdep.cpu.core_count";
    }else if(osValidator.isUnix()){
        command = "lscpu";
    }else if(osValidator.isWindows()){
        command = "cmd /C WMIC CPU Get /Format:List";
    }
    Process process = null;
    int numberOfCores = 0;
    int sockets = 0;
    try {
        if(osValidator.isMac()){
            String[] cmd = { "/bin/sh", "-c", command};
            process = Runtime.getRuntime().exec(cmd);
        }else{
            process = Runtime.getRuntime().exec(command);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    BufferedReader reader = new BufferedReader(
            new InputStreamReader(process.getInputStream()));
    String line;

    try {
        while ((line = reader.readLine()) != null) {
            if(osValidator.isMac()){
                numberOfCores = line.length() > 0 ? Integer.parseInt(line) : 0;
            }else if (osValidator.isUnix()) {
                if (line.contains("Core(s) per socket:")) {
                    numberOfCores = Integer.parseInt(line.split("\\s+")[line.split("\\s+").length - 1]);
                }
                if(line.contains("Socket(s):")){
                    sockets = Integer.parseInt(line.split("\\s+")[line.split("\\s+").length - 1]);
                }
            } else if (osValidator.isWindows()) {
                if (line.contains("NumberOfCores")) {
                    numberOfCores = Integer.parseInt(line.split("=")[1]);
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    if(osValidator.isUnix()){
        return numberOfCores * sockets;
    }
    return numberOfCores;
}

OSValidator class:

public class OSValidator {

private static String OS = System.getProperty("os.name").toLowerCase();

public static void main(String[] args) {

    System.out.println(OS);

    if (isWindows()) {
        System.out.println("This is Windows");
    } else if (isMac()) {
        System.out.println("This is Mac");
    } else if (isUnix()) {
        System.out.println("This is Unix or Linux");
    } else if (isSolaris()) {
        System.out.println("This is Solaris");
    } else {
        System.out.println("Your OS is not support!!");
    }
}

public static boolean isWindows() {
    return (OS.contains("win"));
}

public static boolean isMac() {
    return (OS.contains("mac"));
}

public static boolean isUnix() {
    return (OS.contains("nix") || OS.contains("nux") || OS.contains("aix") );
}

public static boolean isSolaris() {
    return (OS.contains("sunos"));
}
public static String getOS(){
    if (isWindows()) {
        return "win";
    } else if (isMac()) {
        return "osx";
    } else if (isUnix()) {
        return "uni";
    } else if (isSolaris()) {
        return "sol";
    } else {
        return "err";
    }
}

}

adi9090
  • 547
  • 8
  • 12
  • 4
    This is a piece of code that is a good candidate to be OOPed. :) – Lyubomyr Shaydariv Dec 30 '15 at 08:45
  • 1
    The OSValidator class supports OSX, but the getNumberOfCores completely ignores it. As an aside, https://blog.opengroup.org/2015/10/02/mac-os-x-el-capitan-achieves-unix-certification/ so 'Mac' should be in your isUnix() but... For BSD, OSX, no lscpu command exists and your getNumberOfCores will return 0. – Paul Hargreaves Apr 19 '16 at 19:16
  • 1
    On Linux, you have to multiple "Core(s) per socket" by "Socket(s)". Also, I would use regular expressions. – Aleksandr Dubinsky Jun 07 '16 at 16:47
  • 2
    Its better to use "OS.contains()" instead of "OS.indexOf()". It improves readability and is less to type. – JWCompDev Feb 05 '17 at 03:11
14

This is an additional way to find out the number of CPU cores (and a lot of other information), but this code requires an additional dependence:

Native Operating System and Hardware Information https://github.com/oshi/oshi

SystemInfo systemInfo = new SystemInfo();
HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();
CentralProcessor centralProcessor = hardwareAbstractionLayer.getProcessor();

Get the number of logical CPUs available for processing:

centralProcessor.getLogicalProcessorCount();
Antonio
  • 756
  • 7
  • 26
  • 1
    This will also let you use centralProcessor.getPhysicalProcessorCount(), which is probably currently the best way in java to obtain that information. If you have threads which almost constantly have work to do, and you want to know the number of such threads you can start while still leaving a well-defined leftover of CPU capacity for other threads and processes, this is the number the calculation should be based on. – malamut Nov 28 '19 at 09:09
1

If you want to dubbel check the amount of cores you have on your machine to the number your java program is giving you.

In Linux terminal: lscpu

In Windows terminal (cmd): echo %NUMBER_OF_PROCESSORS%

In Mac terminal: sysctl -n hw.ncpu

  • 1
    `%NUMBER_OF_PROCESSORS%` outputs number of [logical](https://serverfault.com/a/646998) cores – alper Aug 19 '22 at 12:06
-7

This works on Windows with Cygwin installed:

System.getenv("NUMBER_OF_PROCESSORS")

rzymek
  • 9,064
  • 2
  • 45
  • 59
Lyle Z
  • 1,269
  • 10
  • 7
  • I have Cygwin installed, but this works from the Windows shell: ```groovy -e "println System.getenv('NUMBER_OF_PROCESSORS')"``` – AbuNassar Apr 01 '17 at 14:23
  • I don't know off the top of my head if this is a standard Windows environment variable, but: ```set NUMBER_OF_PROCESSORS``` works from the Windows command line for me. – AbuNassar Apr 01 '17 at 14:25