threadsicherheit bei singletons

ruutaiokwu

Top Contributor
hallo zusammen,

bin gerade mit diesem thema beschäftigt. wie könnte ich einen test schreiben, der bei nicht synchronisierten singletons zu problemen führt, diese also provoziert?

habe 5 threads starten lassen, alle mit einer endlosschleife in der run()-funktion (habe "Runnable" implementiert...), welche nach 100000 iterationen auf 0 zurückgesetzt wird. in dieser rufe ich die singleton getInstance()-funktion auf, zusätzlich rufe ich eine methode auf, welche sich in der singleton-klasse befindet...

jedoch konnte ich damit noch keinen absturz provozieren. was wäre eignetlich das typische verhalten, wenn etwas nicht synchronisiert ist? exceptions?

irgendwie habe ich keine ahnung von thread, wie ich gerade merke...:-(


grüsse, jan
 

XHelp

Top Contributor
Was willst du denn erreichen? Schau dir einfach mal Theorie zur Synchronisation an, damit du weißt, wozu es überhaupt gemacht wird. Anhand der Beispiele kannst du dann dein Programm basteln.
 
M

maki

Gast
jedoch konnte ich damit noch keinen absturz provozieren.
Wäre mir neu, wenn man dadurch Abstürze produzieren kann.
Schlimmstenfalls werden 2 Instanzen deines Singletons angelegt.

Kannst ja mal ein Thread#sleep einbauen in den Teil, wo das Singleton durch Lazy-Init erzeugt wird.

Wenn es denn unbedingt Lazy-Init sein muss, sieh dir mal das Instance Hodler Idiom (kopiert von WikiPedia):
Java:
 public class Singleton {
 
   // Private constructor prevents instantiation from other classes
   private Singleton() {
   }
 
   /**
    * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
    * or the first access to SingletonHolder.INSTANCE, not before.
    */
   private static class SingletonHolder { 
     public static final Singleton INSTANCE = new Singleton();
   }
 
   public static Singleton getInstance() {
     return SingletonHolder.INSTANCE;
   }
 
 }
Einfacher/Performanter wäre natürlich, auf Lazy-Init zu verzichten, braucht man eigentlich sowieso selten.

Am besten aber wäre, wenn du ohne Singletons auskommen würdest ;)
 

ruutaiokwu

Top Contributor
das problem ist, dass ich eine singleton-konstruktion entwickelt habe, welche ich testen will:
(im oberen auskommentierten bereich ist ein "normales" nicht-threadsicheres singleton)

Java:
public final class MyNewSingleton1
{
  /*
  private static MyNewSingleton1 instance = null;

  public static MyNewSingleton1 getInstance()
  {
    if (instance == null)
    {
      instance = new MyNewSingleton1();
    }

    return instance;
  }
  */

  public String method1(String str)
  {
    return str;
  }

  private static final MyNewSingleton1 instance;

  static
  {
    instance = new MyNewSingleton1();
  }

  private MyNewSingleton1()
  {

  }

  public static MyNewSingleton1 getInstance()
  {
    synchronized (MyNewSingleton1.class)
    {
      if (instance == null)
      {
        new MyNewSingleton1();
      }
    }

    return instance;
  }
}


...ist nur ein experiment, soll nichts "revolutionäres" werden, es haben sich ja schon genug leute mit diesem thema herumgeschlagen.


grüsse, jan
 

ruutaiokwu

Top Contributor
...ist ja ganz "fundiert", ;-), was ich da gemacht habe: wusste gar nicht, dass der static-konstruktor scheinbar beim aufruf der ersten statischen funktion ausgelöst wird.* habe immer gemeint dass dieser bei normalen (new) instanzierungen insgesamt 1x aufgerufen wird.

* was macht das denn für einen sinn? wenn man fast ausschliesslich static-methoden verwendet (ja, es gibt leute die das machen bei java) und praktisch gänzlich auf oo verzichtet, für was braucht man denn sowas wie einen static-konstruktor?


grüsse, jan
 

XHelp

Top Contributor
Das macht schon Sinn, aber man sollte nur das verwendet, was man versteht. Allerdings ist es kein Konstruktor, sondern ein Initialisierer.
Hier ein Stück Code, vllt wird dadurch deutlicher, wozu du es u.A. verwenden kannst:
(Initializing Fields (The Java™ Tutorials > Learning the Java Language > Classes and Objects))
Java:
class Whatever {
    public static varType myVar = initializeClassVariable();
    private static varType initializeClassVariable() {
        //initialization code goes here
    }
}
Das ist eine alternative zu den statischen Initialisierer.
 
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben