Frage

Also habe ich über den Aufbau ein Hobby-Projekt denke, ein off Art der Sache, um nur auffrischen auf meiner Programmierung / Design.

Es ist im Grunde ein Multi-Threaded-Web-Spider, die gleiche Datenstruktur aktualisieren objekt-> int.

So ist es auf jeden Fall viel des Guten ist, eine Datenbank für diese zu verwenden, und das einzige, was ich denken konnte, ist ein Thread-sichere Singleton verwendet, um meine Datenstruktur zu enthalten. http : //web.archive.org/web/20121106190537/http: //www.ibm.com/developerworks/java/library/j-dcl/index.html

Sie haben einen anderen Ansatz ich aussehen in sollte?

War es hilfreich?

Lösung

Doppel geprüft Verriegelung bewährt hat falsch und fehlerhaft (wie zuletzt in Java) sein. Führen Sie eine Suche oder schauen Sie auf Wikipedias Eintrag für den genauen Grund.

In erster Linie ist Programm Richtigkeit. Wenn Ihr Code nicht Thread-sicher (in einer Multithread-Umgebung) ist, dann ist es gebrochen. Correctness kommt zuerst vor Performance-Optimierung.

korrekt sein, werden Sie die ganze getInstance Methode synchronisieren müssen

public static synchronized Singleton getInstance() {
   if (instance==null) ...
}

oder statisch initialisieren

private static final Singleton INSTANCE = new Singleton();

Andere Tipps

Mit verzögerte Initialisierung für die Datenbank in einem Web-Crawler ist wahrscheinlich nicht die Mühe wert. Verzögerte Initialisierung erhöht die Komplexität und eine laufende Geschwindigkeit Hit. Ein Fall, in dem es gerechtfertigt ist, ist, wenn es eine gute Chance ist, werden die Daten niemals benötigt werden. Auch in einer interaktiven Anwendung, kann es verwendet werden, die Startzeit zu verringern und geben Sie die Illusion die Geschwindigkeit.

Für eine nicht-interaktive Anwendung wie ein Web-Crawler, die sicherlich seine Datenbank müssen sofort existieren, faul Initialisierung ist eine schlechte Passform.

Auf der anderen Seite, ein Web-Crawler leicht parallelizable und profitieren stark von Multi-Threaded ist. Mit ihm als eine Übung der java.util.concurrent Bibliothek zu meistern wäre sehr sinnvoll sein. Insbesondere sehen ConcurrentHashMap und < a href = "http://java.sun.com/javase/6/docs/api/java/util/concurrent/ConcurrentSkipListMap.html" rel = "noreferrer"> ConcurrentSkipListMap, die auf mehrere Threads ermöglicht lesen und eine gemeinsame Karte aktualisieren.

Wenn Sie loswerden faul Initialisierung erhalten, ist die einfachste Singleton-Muster ist so etwas wie folgt aus:

class Singleton {

  static final Singleton INSTANCE = new Singleton();

  private Singleton() { }

  ...

}

Das Schlüsselwort final ist hier der Schlüssel. Selbst wenn Sie einen static „Getter“ für die Singleton bieten, anstatt direkten Feldzugriff ermöglicht, so dass der Singleton final Korrektheit hilft sicherzustellen, und ermöglicht aggressivere Optimierung durch die JIT-Compiler.

Wenn Ihr Leben auf wenige Mikrosekunden abhing, dann würde ich Ihnen raten, Ihre Ressourcen zu optimieren Sperren, wo es wichtig tatsächlich.

Aber in diesem Fall ist das Schlüsselwort hier ist Hobby-Projekt !

Was bedeutet, dass, wenn Sie das gesamte getInstance synchronisiert () Methode werden Sie in 99,9% aller Fälle in Ordnung sein. Ich würde nicht empfehlen, es auf andere Weise zu tun.

Wenn Sie später durch Profilierung beweisen, dass die getInstance () Synchronisation der Engpass des Projekts ist, dann können Sie auf verschieben und die Parallelität optimieren. Aber ich bezweifle wirklich, dass es Ihnen Probleme verursacht.

Jeach!

Versuchen Sie, die Bill Pugh Lösung der Initialisierung auf Anfrage Halter Idiom. Die Lösung ist die portable über verschiedene Java-Compiler und virtuelle Maschinen. Die Lösung ist threadsicher ohne spezielle Sprachkonstrukte (d.h. flüchtige und / oder synchronisiert).

http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh

als Joshua Bloch argumentiert in seinem Buch „Effective Java 2nd edition“ Ich bin damit einverstanden, dass ein einzelner Element Aufzählungstyp ist der beste Weg, um einen Singleton zu implementieren.

public enum Singleton {
  INSTANCE;

  public void doSomething() { ... }
}

Wenn Sie ganz am Ende dieses Artikel anschauen, werden Sie den Vorschlag sehen, nur ein statisches Feld zu verwenden. Das wäre meine Neigung zu sein: Sie nicht wirklich brauchen faul Instanziierung (so brauchen Sie nicht getInstance() sowohl eine Accessor und eine Factory-Methode zu sein). Sie wollen nur sicherstellen, dass Sie eine haben und nur eines dieser Dinge. Wenn Sie wirklich globalen Zugriff auf eine solche Sache brauchen, würde ich a href verwenden <= „http://www.ibm.com/developerworks/java/library/j-dcl.html#6“ rel = „nofollow noreferrer“ > dass Codebeispiel auf den Grund :

class Singleton
{
  private Vector v;
  private boolean inUse;
  private static Singleton instance = new Singleton();

  private Singleton()
  {
    v = new Vector();
    inUse = true;
    //...
  }

  public static Singleton getInstance()
  {
    return instance;
  }
}

Beachten Sie, dass die Singleton nun während der Installation von statischen Feldern aufgebaut ist. Dies sollte die Threading Risiken von potenziell Fehlsynchronisations Dinge funktionieren und nicht gegenüber.

Alles, was gesagt, vielleicht das, was Sie wirklich brauchen, ist eine der Thread-sichere Datenstrukturen in dem modernen JDKs. Zum Beispiel, ich bin ein großer Fan der ConcurrentHashMap : (! FTW). Thread-Sicherheit und ich habe den Code nicht schreiben

Warum Sie keine Datenstruktur erstellen Sie zu jedem der Themen als Dependency Injection passieren. Auf diese Weise brauchen Sie nicht einen Singleton. Sie müssen noch den Thread-sicher.

machen

Der Artikel, den Sie nur Gespräche verwiesen über die Schaffung des Singleton-Objekts zu machen, vermutlich eine Sammlung in diesem Fall Thread-sicher. Sie müssen auch eine Thread-sichere Sammlung, so dass die Sammlung Operationen auch wie erwartet. Stellen Sie sicher, dass die zugrunde liegende Sammlung in der Singleton synchronisiert ist, vielleicht ein ConcurrentHashMap .

Sie diesen Artikel Schauen Sie sich Implementierung des Singleton-Muster in C #

public sealed class Singleton
{
    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return Nested.instance;
        }
    }

    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}

Wie wäre:

public static Singleton getInstance() {
  if (instance == null) {
    synchronize(Singleton.class) {
      if (instance == null) {
         instance = new Singleton();
      }
    }
  }

  return instance;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top