Vorteil der Verwendung von statischen Variablen in Java
Sagen, ich habe zwei Klassen, wie diese:
class A{
private static Random random = new Random();
public A(){
//Do something.
}
public Integer methodGetsCalledQuiteOften(){
return random.nextInt();
}
}
class B{
private Random random;
public A(){
random = new Random();
//Do something.
}
public Integer methodGetsCalledQuiteOften(){
return random.nextInt();
}
}
In einem Szenario, wo beide von Ihnen mehrfach instanziert und die beiden Klassen' Instanzen' Methode methodGetsCalledQuiteOften
aufgerufen wird, eine Menge, ist es real Vorteil/Nachteil (Zeit, Speicher) in eine statische variable, die hält Random()
in der Klasse A im Gegensatz zum erstellen einer neuen Random()
Objekt in jedem einzelnen Fall, wie in der Klasse B?
Die Anwendung ist multithreaded und ein höheres Maß an Zufälligkeit ist, so dass ich denke, ich werde mit statischen SecureRandom
. Wenn, dass wird ein echter Geschwindigkeits-Faktor nach Profilierung, die ich wählen könnte, etwas anderes.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Real Vorteile/Nachteile hängen von real code. In anderen Worten, es hängt davon ab, wie oft ein
B
erstellt wird verglichen, wie oft die Methode aufgerufen wird, etc. Sollten Sie ein Profil Ihrer Anwendung und sehen, ob es macht einen vernünftigen Unterschied.Wird Ein schneller als B? Sicherlich. Aber ob Sie jemals bemerken, hängt von Ihrer Nutzung. Wird weniger Speicher als B? Sicherlich, aber ob Sie interessiert oder nicht hängt davon ab, wie viele Fälle von A/B-Sie halten rund.
Wirklich die einzige andere überlegung ist Determinismus. Da Sie nicht angeben, den seed für die Random Instanz, nehme ich es Ihnen egal ist, ob Sie Sie reproduzieren die Reihenfolge der zahlen aus dem Zufallsgenerator. Aber es ist erwähnenswert..., wenn Sie ein gemeinsames Random, wird es viel schwieriger zu garantieren, eine bestimmte deterministische Sequenz von zahlen, die für eine Instanz des Ein als ist es mit einem pro-Instanz wie in B.
Nur Nein sagen zu veränderlich statische, m'kay.
Es ist grauenhaft design. Die üblichen zitierte Folge ist, dass die Testbarkeit ausfällt. Es wird schwierig sein, zu reproduzieren, ohne Neuladen der Klasse. Schlechtes design ist auch schlecht für viele andere Gründe. Nur zu erwähnen, Klassen sollten standardmäßig thread-Agnostiker. Fügen Sie eine mutable statische und Sie sind thread-feindlich - ein schlechter Platz zu sein.
Erstellen einer neuen Instanz jedes mal scheint verschwenderisch. Obwohl, natürlich, nicht die Optimierung vorzeitig (wenn Sie waren zu optimieren, würden Sie nicht mit
java.util.Random
). Die ersten sehen Inkrementieren könnte auch Probleme verursachen.Der beste Ansatz ist der pass in einer Instanz ("Parametrieren von Oben" oder "mit Konstruktoren richtig"). Dann können Sie testen, zu reproduzieren, zu verspotten, etc. Sie sind effizient und leicht schlagen können, in einer anderen Implementierung.
Wenn Ihr Programm ist single-threaded, Ihre
Random
sollte ein Schüler (static
). Das ist ein bisschen effizienter. Es ist umso wichtiger, wenn mit einemSecureRandom
, die eine relativ lange Zeit, um Samen zunächst.Wenn mehrere threads am Ende aufrufen
methodGetsCalledQuiteOften()
, das Problem ist ein bisschen komplizierter. Die Klasse ist thread-sicher, aber der Aufwand erforderlich, um zu schützen, Ihren Zustand während der gleichzeitigen änderungen vielleicht vergleichbar zu machen neue, unabhängige InstanzenRandom
.Ich würde wahrscheinlich stick mit einer
static
Mitglied, bis ich bemerkte eine Menge von Konflikten zwischen threads für den Zufallszahlengenerator, der wird wahrscheinlich nie passieren.SecureRandom
wird wahrscheinlich laden ein laden, der security Infrastruktur und dauern ewig. Aber danach sollte es relativ flott, wenn auch nicht so schnell wie die alten, vorhersehbarenjava.util.Random
.Obwohl die Instanziierung der Klasse A ist substantialy (10x) schneller als der Klasse B, dieser ist nur von Bedeutung, wenn Sie dies tun, wie 100.000 mal in der Sekunde.
Etwa thread-Sicherheit, es ist mein Verständnis, dass .nextInt() basiert auf .next() das sollte thread-sicher. Also multi-threading sollte keine Probleme hier.
Aber noch wichtiger ist, das Verhalten beider Klassen anders sein kann. Instanzen der Klasse A geben Sie jedem eine etwas zufällige Reihenfolge von zahlen, sondern Instanzen der Klasse B könnte jeder die gleiche Sequenz von 'zufälligen' zahlen (dieses Verhalten kann unterschiedlich sein, die auf verschiedenen Plattformen!). Die Javadoc spec Staaten:
So, wenn die Zufälligkeit ist wichtig, möchten Sie vielleicht zu erwägen, einen einzigartigen Samen, um die Random-Konstruktor oder besser implementieren, die Zufällig mit dem langsameren java.Sicherheit.SecureRandom.
Verwenden Sie eine statische variable, wenn die Instanz ist nicht zu erwarten, zu ändern oder, wenn Sie wollen, es zu teilen zwischen den Instanzen.
ist ein Beispiel.
anderer sein könnte. Im letzteren Fall, erwarten wir nicht, dass die Staaten ändern sich von Instanz zu Instanz. So ist macht keinen Sinn für jede Instanz eine eigene Kopie.
final
undCollections.unmodifiableMap
dort?final
aus, mehr wie die OP ' s code. Ich erinnere mich nicht, jemals verwendenstatic
ohnefinal
jedoch.final
s. Gute Beobachtung.Zugriff auf statische Ressourcen ist nicht thread-sicher. Sie bekommen vielleicht komisch/unvorhersehbare Ergebnisse in einer Multithread-Umgebung.
Gut, da
Random
Klasse ergreift die notwendigen Schritte, um sicherzustellen, thread-safety, sehe ich kein problem mit macht es statisch.Seit Ihrer Staates umfasst die einzelnen
AtomicLong
Objekt (8 Byte), es ist keine große Verschwendung von Speicher (es sei denn, Sie planen, erstellen riesige Höhe vonB
Instanzen).So, ich würde sagen, es gibt wenig Unterschied oder so.
Random
, statt uns unter Berufung auf die code-Inspektion.Random
ist thread-safe, nur nicht eindeutig: "Die Methode weiter implementiert durch die Klasse Random durch atomar aktualisieren der Samen ..."Wenn Sie
java.util.Random
, beachten Sie, dass es ist ein linear congruential generator mit bekannten Problemen in Zusammenhang mit der Korrelation. Für mich, die eigentliche Frage ist, ob die Anwendung wählen Sie aus einer Reihe oder aus mehreren, mit verschiedenen Samen.In Bezug auf Zeit und Speicher ich kann mir nicht vorstellen, dass es eine große Vorteile (die statische variable wird ein Teil der definition der Klasse, anstatt auf dem heap). Jedoch statische Variablen sind nützlich, wenn Sie wissen, es wird Zugriffe auf das Objekt von mehreren stellen. hvgotcodes richtig ist aber, dass die Verwendung von statischen Ressourcen ist nicht thread-safe. Aber wenn Ihr nur das Lesen der statische Wert dann unter Verwendung von Fäden für Sie in Ordnung ist.
Werde es speichern Sie von dem pass Verweise auf die eingeleiteten Objekt (A oder B) in andere Objekte, um zu verwenden
random
Vorteile von statischen Variablen (die wichtigsten Punkte):
Konstanten können definiert werden, ohne zusätzlichen Speicher (eine für jede Klasse).
Konstanten zugegriffen werden kann, ohne eine Instanziierung der Klasse.
Vorteile der statischen Methoden:
Instanz-unabhängig Verhalten kann definiert werden, ohne Angst vor versehentlichen Interaktion mit einer Instanz der Klasse.