2 Stimmen

Wie schlecht ist new Thread().sleep im Vergleich zu Thread.sleep in Bezug auf die CPU- und Speichernutzung?

Mir ist bewusst, dass der Zugriff auf sleep in einem statischen Kontext erfolgen sollte. Ich benötige jedoch mehr Informationen, damit ich dies gegenüber dem Management verteidigen kann. Der meiste Legacy-Code, den ich bearbeite, verwendet jetzt new Thread().sleep anstelle von Thread.sleep.

Wie schlimm ist das?

for (int c = 0; c < 5; c++) {
    new Thread().sleep(5000);
}

im Vergleich zu diesem?

for (int c = 0; c < 5; c++) {
    Thread.sleep(5000);
}

EDIT:

    final long start = System.currentTimeMillis();
    System.out.println("Total memory: " + Runtime.getRuntime().totalMemory());
    System.out.println("Free memory: " + Runtime.getRuntime().freeMemory());
    System.out.println("===========================");
    for (int c = 0; c < 5; c++) {
        new Thread().sleep(5000);
        System.out.println("Used memory: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
        System.out.println("===========================");
    }
    System.out.println("Total memory: " + Runtime.getRuntime().totalMemory());
    System.out.println("Free memory: " + Runtime.getRuntime().freeMemory());
    System.out.println("===========================");
    System.out.println("Time elapsed: " + (System.currentTimeMillis() - start) + " milliseconds");

Ergebnis (new Thread().sleep):

Total memory: 5177344
Free memory: 4990904
===========================
Used memory: 186440
===========================
Used memory: 205136
===========================
Used memory: 205136
===========================
Used memory: 205136
===========================
Used memory: 205136
===========================
Total memory: 5177344
Free memory: 4972208
===========================
Time elapsed: 24938 milliseconds

Ergebnis (Thread.sleep):

Total memory: 5177344
Free memory: 4990904
===========================
Used memory: 186440
===========================
Used memory: 186440
===========================
Used memory: 204848
===========================
Used memory: 204848
===========================
Used memory: 204848
===========================
Total memory: 5177344
Free memory: 4972496
===========================
Time elapsed: 24938 milliseconds

0 Stimmen

In beiden Fällen ist die Ruhezeit um mehrere Größenordnungen länger als der "Overhead" von new Thread() . Dennoch stimme ich dem zu, was EJP weiter unten sagt.

0 Stimmen

@all sorry für meine Antwort.. ich habe nicht gesehen, dass Java-Tag.. ich antwortete im Kontext der C#.. Mein Fehler :(

0 Stimmen

@Shekhar: Keine Sorge, es ist nicht persönlich. Ablehnende Bewertungen erfolgen ausschließlich, weil die Antwort hier nicht zutrifft.

9voto

user207421 Punkte 297318

Das ist schlicht und ergreifend Analphabetentum. Dasselbe gilt für den Aufruf jeder statischen Methode auf diese Weise, nicht nur für Thread.sleep(). Es verursacht sinnlose Platz- und Zeitkosten, aber schlimmer noch, es verrät ein großes konzeptionelles Missverständnis seitens des Programmierers. Ich würde nicht viel Energie darauf verwenden, zurückzugehen und alle Vorkommnisse zu beheben, aber ich würde auf jeden Fall etwas tun, um das betroffene Personal umzuschulen.

1 Stimmen

Braucht es wirklich so viel Energie, nur um alle Vorkommen von "new Thread().sleep(...)" durch "Thread.sleep(...)" zu ersetzen? Auch ohne IDEs, find + sed kann die Arbeit erledigen!

0 Stimmen

@Bruno: Das ist wahr, aber manchmal lohnt es sich nicht, die VCS-Geschichte für so etwas zu verwechseln. "Wer war der letzte, der den Code angefasst hat, bevor er kaputt ging?"

0 Stimmen

@Bruno: Ja, das kann es, wenn es Dutzende oder Hunderte von Vorkommen gibt und sie über viele Dateien verstreut sind, die alle an andere Entwickler ausgecheckt sind. Es kann sogar völlig unmöglich sein.

4voto

Tomasz Nurkiewicz Punkte 322861

Zusätzlich zu dem, was bereits gesagt wurde: Wenn Sie bereits alten Code umschreiben, ist dies wahrscheinlich die idiomatischste und einfachste Art, den Schlaf auszudrücken (Sie können natürlich andere Zeiteinheiten verwenden):

TimeUnit.SECONDS.sleep(5);

2voto

Stephen C Punkte 665668

Wie schlimm ist es? Wahrscheinlich nicht wirklich schlecht, was die Leistung angeht.

Meinem Verständnis nach geschieht der teure Teil der Thread-Instanziierung nur, wenn Sie die Thread.start() . Während des Baus des Gebäudes wird jedoch eine Menge Arbeit geleistet Thread Objekt:

  • Initialisierung einer Reihe von Feldern,
  • Sicherheitskontrollen durchführen,
  • et cetera.

Wenn Sie nachweisen wollen, dass es sich um ein signifikantes Leistungsproblem handelt, müssen Sie ein Profil Ihrer Anwendung erstellen. (Und ich habe meine Zweifel, dass es würde signifikant sein.)

Aber es sollte nicht schwer / teuer sein, es zu reparieren ... es sei denn, Sie leben in einer Welt, in der jede Änderung ist schwer / teuer ... oder es sei denn, Ihre Anwendung tut einige ernsthaft seltsame / gebrochene Dinge mit ThreadGroups oder vererbbaren ThreadLocals.

Meine Hauptbeschwerde wäre, dass es so hässlich ist wie das nördliche Ende einer Kuh, die nach Süden läuft. Auf einer Stufe mit der Bezeichnung new String(...) überall auf der Welt.


Ich glaube nicht, dass Ihr Benchmark viel aussagt. Der Overhead für die Erstellung eines unerwünschten Threads liegt wahrscheinlich im Bereich von einer Mikrosekunde oder so. Das ist im Rauschen untergegangen. Außerdem ist Ihre Methodik zur Messung der Speichernutzung schlichtweg falsch. Die totalMemory() y freeMemory() Methoden geben Ihnen Speicherstatistiken, die beim letzten GC-Lauf aufgezeichnet wurden.

0 Stimmen

Ich habe meinen Beitrag aktualisiert. Ich bin mir nicht sicher, ob meine Art zu messen richtig ist. Vielen Dank für Ihre Antwort.

0 Stimmen

Während init der Thread registriert sich auch als nicht gestartet in der ThreadGroup, was später zu einigen Problemen führt...

0 Stimmen

@bestsss - Ich weiß. Versuchen Sie, das @EJP zu erklären, der davon überzeugt ist, dass es keine Probleme geben kann. (IMO gilt alles, was eine Anwendung mit ThreadGroups macht, als "seltsam").

2voto

bestsss Punkte 11264

Eigentlich kostet es ziemlich viel:

new Thread() ist in der Tat ein teurer Anruf (nicht so viel wie Thread.start() natürlich), sondern beinhaltet Stack Crawl, einige synchronisierte Blöcke, einige Sicherheitsüberprüfungen, Kopie der geerbten Thread-Locals und so weiter. Unter dem Sicherheitsmanager kann es auch chaotisch werden.

Vor 1.3 verursachten die nicht gestarteten Threads ein schweres Speicherleck... Jetzt ist es immer noch ein Problem: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4229558 ThreadGroup meldet einen falschen ThreadCount UND kann negativ werden... aber das Schlimmste ist, dass es immer noch ein Leck gibt, da die ThreaGroup nicht pufft ( destroy() ), nachdem alle Threads beendet wurden, sofern sie nicht von Hand verworfen wurden. Letzteres kann problematisch sein, da man warten muss, bis alle Threads ordnungsgemäß beendet sind, und danach den Aufruf destroy() . Klingt einfach, ist aber ein echtes Problem für verwaltete Umgebungen (nämlich den Container).

bearbeiten Da es nicht klar ist, dass ThreadGroup Unterklassen sein können, um die uncaughtException(Thread t, Throwable e) und mit dem Wurfobjekt umgehen. Das macht die ThreadGroup-Klasse hält Referenz auf den Classloader und das Problem ist real. (nicht nur ein kleines Leck bei einem einzelnen Objekt)

Insgesamt haben nicht gestartete Threads Java seit seinen Anfängen genervt, es wäre besser, den Code zu ersetzen. Es wird weniger Zeit in Anspruch nehmen, als ich die Antwort geschrieben habe (hauptsächlich, um etwas Licht in die geglaubte freie Initialisierung zu bringen).

1voto

helloworld922 Punkte 10543

Wenn ich richtig verstanden habe, wie Java mit statischen Methoden umgeht, ruft die erste Methode immer noch die statische Version von sleep() auf, zusätzlich zur Erstellung eines neuen Thread-Objekts. Es ist fast immer besser, die zweite Methode zu verwenden, weil man weiß, dass die Methode statisch ist, wenn man sie in Bezug auf die Klasse und nicht auf eine Instanz aufruft.

Wenn Sie in der Lage sind, diese Code-Anweisungen schnell zu finden und zu ersetzen, würde ich sagen, es lohnt sich. Da jedoch beide Codes funktionieren, glaube ich nicht, dass dies etwas ist, das Sie übermäßig besorgt sein sollte.

1 Stimmen

Eine Sache, die ich über Computer gelernt habe (eigentlich über die meisten Dinge im Allgemeinen) ist, niemals nie zu sagen, und niemals immer zu sagen, denn es könnte ja jemand kommen und dir das Gegenteil beweisen :P

0 Stimmen

Alors beweisen Ich habe mich geirrt. Nennen Sie mir einen Fall, in dem der Aufruf eines statischen Objekts über ein temporäres Objekt, das nur zu diesem Zweck konstruiert wurde, besser ist als der statische Aufruf.

1 Stimmen

Jemand != ich, ich persönlich kann mir keinen Fall vorstellen, in dem dies der Fall wäre

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X