2016-08-04 5 views
1

Die Fragen zu beenden:Wie man misst, wie lange ein Thread genau aus neuen nehmen in Java

  1. ist es trotzdem, um die genaue Zeit, um einen Faden von neuen nehmen zu beenden?
  2. Warum haben die Ergebnisse zu jeder Zeit große Unterschiede (siehe Code unten)?

der Code:

public void process2(){ 
    final long start = System.currentTimeMillis(); 
    Thread newT = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      // long end = System.currentTimeMillis(); 
      // System.out.println((end-start)); 

      for (int i = 1, sum = 0; i < 1000; i++) { 
       sum += i; 
      } 
     } 
    }); 
    long end1 = System.currentTimeMillis(); 
    System.out.println("new thread time took :" + (end1 - start)); 
    newT.start(); 

    int i = 0; 
    while (newT.isAlive()) { 
     i++; 
    } 

    long end = System.currentTimeMillis(); 
    System.out.println("total time:" + (end - start)); 
    System.out.println("judge count:" + i); 

} 
+0

Versuchen Sie Google Suche nach "Kontextwechsel" und "Software-Threads" – DwB

+0

Sie messen auch die Main-Thread-Zeit, die While-Schleife, die ständig prüft, ist die Alive stiehlt CPU-Zyklen, stattdessen können Sie verwenden – ravthiru

Antwort

1
  1. Es ist in der Regel die entsprechenden Ausführungszeitpunkt zu messen, das ist die Zeit genommen run() Methode auszuführen. Diese Zeit wird im Allgemeinen zwischen verschiedenen Läufen ähnlich sein.

  2. Die Schöpfung auf ein neues Thread Objekt ist ziemlich teuer und hängt von derzeit verfügbaren Ressourcen des Systems, weshalb gibt es große Unterschiede in der Zeit genommen zwischen Thread Schöpfung und ihrer Durchführung werden kann. Außerdem gibt es vor der Zerstörung eines Threads einen Aufräumvorgang, der auch viel Zeit in Anspruch nehmen kann.

One Möglichkeiten, um die Thread-Management-Zeit (creations/Zerstörung) verwenden, um ein ThreadPool oder ein ExecutorService zu optimieren. Weitere Informationen finden Sie in Oracle concurrency tutorial.

0

Sie haben ein sehr schlechtes Beispiel für die Messung gekocht.

Zuerst erstellen Sie einen neuen Thread mit neuen tot billig (es ist ein einfaches Java-Objekt). Aber du fügst tatsächlich die Ladezeit für deine anonyme Runnable ein. Dies wird I/O beinhalten, so dass seine erwartet wird, dass die Ausführungszeit ziemlich viel variiert, besonders beim ersten Durchlauf.

Dann messen Sie die Zeit in Millisekunden. Aber die Systemzeit hat nicht unbedingt eine tatsächliche Millisekundenauflösung (lesen Sie die Javadocs von System.currentTimeMillis). Auch das, was Sie zu messen versuchen, wird die meiste Zeit in weniger als eine Millisekunde ausführen.

Ihr Runnable hat keine beobachtbaren Nebenwirkungen, daher wird das JIT wahrscheinlich nur den gesamten Code nach einem kurzen Warmup optimieren. Nach ein paar Läufen braucht das Runnable tatsächlich gar keine Zeit.

Sie sind Abfrage um festzustellen, wenn der andere Thread endet. Das hält die CPU (gut ein Kern, wenn Sie mehr als einen haben) damit beschäftigt nichts nützliches zu tun. Für eine einkernige Maschine bedeutet dies, dass im Durchschnitt 50% der Zeit damit verbracht wird, nichts zu tun, als zu überprüfen, ob der Thread am Leben ist. Je nachdem, wie der OS-Scheduler die Threads ausführt, ist dies eine weitere Variationsquelle.

Alles in allem haben Sie eine Microbenchmark gekocht und Sie sind in all die häufigsten Fallstricke getreten, dass Mikrobenchmarks in Java leiden können. Benchmarking in Java erfordert etwas Sorgfalt, oder Sie messen alles, aber nicht die Leistung des Codes, den Sie eigentlich messen möchten. Es gibt Benchmarking-Frameworks und auch hervorragende Artikel zum Thema Benchmarking in Java, sowie eine Menge verwandter Fragen hier zur SO. Nutzen Sie diese Ressourcen.

+0

tiefe Analyse, Danke – star