Trovare il numero di core in Java


412

Come posso trovare il numero di core disponibili per la mia applicazione all'interno del codice Java?


3
Per praticamente tutti gli scopi "core == processor".
Joachim Sauer,

32
trovare il numero di core che la macchina ha fisicamente è difficile usando puramente Java. Trovare il numero di core che il programma Java può usare all'avvio è facile, usando Runtime.getRuntime (). AvailableProcessors () . A causa della capacità di tutti i principali sistemi operativi moderni di impostare l'affinità della CPU (ovvero limitare un'applicazione a un determinato numero di core), questa è una preoccupazione da tenere a mente.
SyntaxT3rr0r

6
Nuclei logici o fisici? C'è una differenza importante.
b1nary.atr0phy

Risposte:


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

Se coresè inferiore a uno, o il tuo processore sta per morire, o la tua JVM ha un grave bug o l'universo sta per esplodere.


107
Questo ti darà il numero di thread logici. ad esempio, se hai l'hyper-threading, questo sarà il doppio del numero di core.
Peter Lawrey,

6
@Peter, sì, buon punto. Mi sono sentito King of the Hill quando ho eseguito questa azione con la mia macchina i7! :)
Bart Kiers,

14
@Peter Lawrey: fornisce solo il numero di thread logici effettivamente disponibili per la JVM (credo all'avvio). Utilizzando l'affinità della CPU, l'utente / il sistema operativo possono limitare il numero di "core" visualizzati da una JVM. Puoi persino farlo su una JVM in esecuzione ma non sono troppo sicuro di come questa influenza sia disponibileProcessori () .
SyntaxT3rr0r

25
@PeterLawrey: che sembra essere errato, la documentazione Java per availableProcessors () dice "Questo valore può cambiare durante un particolare richiamo della macchina virtuale. Le applicazioni sensibili al numero di processori disponibili dovrebbero quindi effettuare occasionalmente il polling di questa proprietà e regolare il loro utilizzo delle risorse in modo appropriato. " fonte
JW.

9
@universe che esplode e così: o la macchina ha effettivamente più di 2.147.483.647 thread logici disponibili? ;)
Pierre Henry,

26

Se si desidera ottenere il numero di core fisici, è possibile eseguire cmd e il comando terminal e quindi analizzare l'output per ottenere le informazioni necessarie. Di seguito viene mostrata la funzione che restituisce il numero di core fisici.

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;
}

Classe OSValidator:

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.indexOf("win") >= 0);
}

public static boolean isMac() {
    return (OS.indexOf("mac") >= 0);
}

public static boolean isUnix() {
    return (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0 || OS.indexOf("aix") > 0 );
}

public static boolean isSolaris() {
    return (OS.indexOf("sunos") >= 0);
}
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";
    }
}

}


4
Questo è un pezzo di codice che è un buon candidato per essere OOPed. :)
Lyubomyr Shaydariv il

1
La classe OSValidator supporta OSX, ma getNumberOfCores lo ignora completamente. A parte questo, blog.opengroup.org/2015/10/02/… , quindi 'Mac' dovrebbe essere nel tuo isUnix () ma ... Per BSD, OSX, non esiste alcun comando lscpu e getNumberOfCores restituirà 0.
Paul Hargreaves,

1
Su Linux, devi "Core (s) per socket" per "Socket (s)". Inoltre, userei le espressioni regolari.
Aleksandr Dubinsky,

1
È meglio usare "OS.contains ()" invece di "OS.indexOf ()". Migliora la leggibilità ed è meno da digitare.
Josh Gager,

6

Questo è un modo aggiuntivo per scoprire il numero di core della CPU (e molte altre informazioni), ma questo codice richiede una dipendenza aggiuntiva:

Sistema operativo nativo e informazioni sull'hardware https://github.com/oshi/oshi

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

Ottieni il numero di CPU logiche disponibili per l'elaborazione:

centralProcessor.getLogicalProcessorCount();

Questo ti permetterà anche di usare centralProcessor.getPhysicalProcessorCount (), che probabilmente è attualmente il modo migliore in Java per ottenere tali informazioni. Se hai thread che hanno quasi sempre del lavoro da fare e vuoi sapere il numero di tali thread che puoi avviare lasciando comunque un residuo ben definito della capacità della CPU per altri thread e processi, questo è il numero che dovrebbe essere il calcolo basato su.
Malamut,

-3

Funziona su Windows con Cygwin installato:

System.getenv("NUMBER_OF_PROCESSORS")


Ho installato Cygwin, ma funziona dalla shell di Windows:groovy -e "println System.getenv('NUMBER_OF_PROCESSORS')"
AbuNassar,

Non so se sia una variabile d'ambiente standard di Windows, ma: set NUMBER_OF_PROCESSORSfunziona dalla riga di comando di Windows per me.
AbuNassar,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.