Thomas Darimont
Erfahrenes Mitglied
Hallo,
dieser Beitrag erklärt das erzeugende Muster: Singleton
- Beispiele Verschiedene Singleton Varianten
- Probleme aufzeigen (Visibility, Threading, Seralisierung, ClassLoader Problematik)
Ausgabe:
Gruß Tom
dieser Beitrag erklärt das erzeugende Muster: Singleton
- Beispiele Verschiedene Singleton Varianten
- Probleme aufzeigen (Visibility, Threading, Seralisierung, ClassLoader Problematik)
Java:
package de.tutorials.design.patterns.creational;
import java.net.URL;
import java.net.URLClassLoader;
public class SingletonPatternExample {
public static void main(String[] args) {
System.out.println(SingletonWithDCL.getInstance());
System.out.println(SingletonWithDCL.getInstance());
System.out.println(SingletonWithEagerInitialization.getInstance());
System.out.println(SingletonWithEagerInitialization.getInstance());
System.out.println(SingletonWithHolder.getInstance());
System.out.println(SingletonWithHolder.getInstance());
System.out.println(EnumBaseSingleton.INSTANCE + " " + System.identityHashCode(EnumBaseSingleton.INSTANCE));
System.out.println(EnumBaseSingleton.INSTANCE + " " + System.identityHashCode(EnumBaseSingleton.INSTANCE));
demoMultiClassloaderProblem();
}
public static class TestEnv{
public static void run() {
System.out.println("Current classloader: " + TestEnv.class.getClassLoader());
System.out.println(SingletonWithHolder.getInstance());
System.out.println(SingletonWithHolder.getInstance());
}
}
private static void demoMultiClassloaderProblem() {
System.out.println("#### demoMultiClassloaderProblem");
try {
newTestEnv().getMethod("run").invoke(null);
newTestEnv().getMethod("run").invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
}
protected static Class<?> newTestEnv() throws ClassNotFoundException {
URLClassLoader classLoader = new URLClassLoader(new URL[]{TestEnv.class.getProtectionDomain().getCodeSource().getLocation()},null /* no parent classloader */);
Class<?> clazz = classLoader.loadClass(TestEnv.class.getName());
return clazz;
}
public static class SingletonWithDCL{
private static volatile SingletonWithDCL instance; //volatile is very important here -> only volatile guarantees that other threads
//can "see" the changed value
private SingletonWithDCL() {} //private constructor to prevent instantiation
public static SingletonWithDCL getInstance(){
if(instance == null){ //DCL = Double Checked Locking
synchronized (SingletonWithDCL.class) {
if(instance == null){
instance = new SingletonWithDCL();
}
}
}
return instance;
}
private Object readResolve(){
return getInstance(); //return the existing instance during serialization
}
}
public static class SingletonWithEagerInitialization{
private static final SingletonWithEagerInitialization instance = new SingletonWithEagerInitialization(); // classloader guarantees initialization
private SingletonWithEagerInitialization(){}
public static SingletonWithEagerInitialization getInstance() {
return instance;
}
private Object readResolve(){
return instance;
}
}
public static class SingletonWithHolder{
private static class Holder{
private static final SingletonWithHolder instance = createInstance();
public static SingletonWithHolder createInstance() {
return new SingletonWithHolder();
}
}
public static SingletonWithHolder getInstance(){
return Holder.instance; //classloader ensures class / singleton initialization
}
private Object readResolve(){
return getInstance();
}
}
public static enum EnumBaseSingleton{
INSTANCE;
}
}
Ausgabe:
Code:
de.tutorials.design.patterns.creational.SingletonPatternExample$SingletonWithDCL@4fe5e2c3
de.tutorials.design.patterns.creational.SingletonPatternExample$SingletonWithDCL@4fe5e2c3
de.tutorials.design.patterns.creational.SingletonPatternExample$SingletonWithEagerInitialization@164f1d0d
de.tutorials.design.patterns.creational.SingletonPatternExample$SingletonWithEagerInitialization@164f1d0d
de.tutorials.design.patterns.creational.SingletonPatternExample$SingletonWithHolder@45bab50a
de.tutorials.design.patterns.creational.SingletonPatternExample$SingletonWithHolder@45bab50a
INSTANCE 1807500377
INSTANCE 1807500377
#### demoMultiClassloaderProblem
Current classloader: java.net.URLClassLoader@544a5ab2
de.tutorials.design.patterns.creational.SingletonPatternExample$SingletonWithHolder@6af62373
de.tutorials.design.patterns.creational.SingletonPatternExample$SingletonWithHolder@6af62373
Current classloader: java.net.URLClassLoader@459189e1
de.tutorials.design.patterns.creational.SingletonPatternExample$SingletonWithHolder@527c6768
de.tutorials.design.patterns.creational.SingletonPatternExample$SingletonWithHolder@527c6768
Gruß Tom