2012-11-16 12 views
17

Ziel: Führen Sie bestimmten Code hin und wieder aus.Thread.sleep() VS Executor.scheduleWithFixedDelay()

Frage: In Bezug auf Leistung, gibt es einen signifikanten Unterschied zwischen:

while(true) { 
    execute(); 
    Thread.sleep(10 * 1000); 
} 

und

executor.scheduleWithFixedDelay(runnableWithoutSleep, 0, 10, TimeUnit.SECONDS); 

?

Natürlich ist die letztere Option koscherer. Dennoch würde ich gerne wissen, ob ich mich auf ein Abenteuer mit dem Titel "Verbringe ein paar Tage Refactoring von altem Code, um sich von Thread.sleep() zu verabschieden" beginne.

Aktualisierung: Dieser Code läuft in Super/Mega/Hyper-High-Load-Umgebung.

+0

genommen Ich denke, beide sind gleich und 'scheduleWithFixedDelay' Schlaf Anruf gekapselt. –

+1

@Quoi: Sie sind nicht wirklich identisch, da der geplante Executor viele geplante Tasks ausführen kann und sie in weniger Threads als die Anzahl der Tasks ausführen kann. Wenn Sie nur schlafen, müssen Sie einen Thread für jede Aufgabe haben, die Sie "planen". –

+5

Warum fragen Sie nach der Leistung einer * Schlaf * -Operation? – Dan

Antwort

6

Sie haben es mit Schlafzeiten zu tun, die in Zehntelsekunden angegeben sind. Die möglichen Einsparungen durch Ändern der Schlafoption sind hier wahrscheinlich Nanosekunden oder Mikrosekunden.

Ich würde den letzteren Stil jedes Mal bevorzugen, aber wenn Sie den ehemaligen haben und es kostet Sie viel, es zu ändern, "Verbesserung der Leistung" ist keine besonders gute Begründung.

EDIT re: 8000 Gewinde

8000 Fäden ist eine ganze Menge; Ich wechsle zum geplanten Executor, um die Auslastung Ihres Systems zu steuern. Ihr Punkt über unterschiedliche Weckzeiten ist etwas, auf das Sie achten sollten, obwohl ich argumentieren würde, dass das größere Risiko ein Ansturm von Threads ist, die alle schlafen und dann in kurzer Folge aufwachen und um alle Systemressourcen konkurrieren.

Ich würde die Zeit verbringen, diese alle in einem festgelegten Thread-Pool geplanten Executor zu werfen. Es werden nur so viele gleichzeitig ausgeführt, wie Sie für die am meisten eingeschränkte Ressource (z. B. # Kerne oder # IO-Pfade) zur Verfügung haben, sowie einige wenige, die einen Slop aufnehmen können. Dadurch erhalten Sie einen guten Durchsatz auf Kosten der Latenz.

Mit der Thread.sleep() Methode wird es sehr schwer zu kontrollieren, was vor sich geht, und Sie werden wahrscheinlich beide Durchsatz und Latenz verlieren.

Wenn Sie detailliertere Ratschläge benötigen, müssen Sie wahrscheinlich beschreiben, was Sie genauer ausführen möchten.

+0

Meine Sorge ist, dass wir 8.000 Threads haben und die schlafenden Threads eine so niedrige Priorität bekommen, dass sie mit einer erheblichen Verzögerung ausgeführt werden, was möglicherweise zu Problemen mit GC führen kann. – rudgirello

1

Da Sie die Java-Version nicht erwähnt haben, können sich die Dinge ändern.

Wie ich aus dem Quellcode von Java erinnere, ist der Hauptunterschied, der kommt, die Art, wie die Dinge intern geschrieben werden.

Für Sun Java 1.6, wenn Sie den zweiten Ansatz verwenden, der native Code bringt auch in der warten und Anrufe an das System melden. Also, mehr Thread-tauglich und CPU-freundlich.

Aber dann wieder verlieren Sie die Kontrolle und es wird für Ihren Code unberechenbarer - denken Sie, Sie möchten für 10 Sekunden schlafen.

Also, wenn Sie mehr Vorhersagbarkeit wollen - sicherlich können Sie mit Option 1 gehen.

Außerdem, in den Legacy-Systemen, wenn Sie solche Dinge begegnen - 80% Chancen gibt es jetzt bessere Möglichkeiten, es zu tun - aber die magischen Zahlen gibt es aus einem Grund (der Rest 20%) so , es auf eigene Gefahr ändern :)

1

es gibt verschiedene Szenarien,

  1. der Timer erstellt eine Warteschlange von Aufgaben, die ständig aktualisiert wird. Wenn der Timer fertig ist, wird möglicherweise nicht sofort Müll gesammelt. Wenn Sie mehrere Timer erstellen, werden nur weitere Objekte auf dem Heap hinzugefügt. Thread.sleep() unterbricht nur den Thread, so dass der Speicheraufwand extrem niedrig ist.
  2. Timer/TimerTask berücksichtigt auch die Ausführungszeit Ihrer Aufgabe, daher wird es etwas genauer. Und es behandelt besser Multithreading-Probleme (wie zum Beispiel Deadlocks etc. vermeiden).
  3. Wenn Sie Thread erhalten Ausnahme und wird getötet, das ist ein Problem. Aber TimerTask wird sich darum kümmern. Es wird unabhängig von einem Fehler im vorherigen Lauf ausgeführt
  4. Der Vorteil von TimerTask ist, dass es Ihre Absicht viel besser ausdrückt (d. H. Lesbarkeit des Codes), und es hat bereits die Funktion cancel() implementiert.

Es wird von here