标签:load tin private efault com alac 宝贝 registry sts
你呱呱落地到这个世界的时候,这就是单例的产生,你是世界上唯一无二的存在。
此时,你是父辈、祖辈的宝贝。他们都想和你亲近。
public class Singleton {
private final static Singleton INSTANCE = new Singleton(); //婴儿呱呱落地
// Private constructor suppresses
private Singleton() {}
// default public constructor
public static Singleton getInstance() { //每个人都想抱你,和你亲近,你也想很多人亲近。
return INSTANCE;
}
}
亲近就有两种:一种:别人想要抱你;另一种:你呼唤别人抱你。
第一种称之为:Eager initialization,如上面的代码所示。另一种称之为Lazy initialization。代码如下所示:
public class SingletonDemo {
private static SingletonDemo instance = null; //我很懒,你要想报我,你自己动手
private SingletonDemo() { }
public static SingletonDemo getInstance() {
if (instance == null) {
instance = new SingletonDemo (); //你得到机会了。
}
return instance;
}
}
竞争的产生
很多人想报你和你亲近,可你只有一个呀,这就产生了矛盾,这就需要你来控制谁可以来抱你了。这就需要synchronization来控制。
public class SingletonDemo {
private static SingletonDemo instance = null;
private SingletonDemo() { }
public static synchronized SingletonDemo getInstance() {
if (instance == null) {
instance = new SingletonDemo ();
}
return instance;
}
}
为了让更多人可以抱你,你想出了更好的办法:
public class SingletonDemo {
private static volatile SingletonDemo instance = null;
private SingletonDemo() { }
public static SingletonDemo getInstance() {
if (instance == null) {
synchronized (SingletonDemo .class){
if (instance == null) {
instance = new SingletonDemo ();
}
}
}
return instance;
}
}
当然,因为怕出现问题,你想出了更巧的办法:双重检查锁
(Double-checked locking)
public static Singleton getInstance() {
if(singleton == null) {
synchronized(Singleton.class) {
if(singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
上述方法存在一定的风险,你可以在方法上再加入synchronized。
public class Singleton {
public final static Singleton INSTANCE = new Singleton();
private Singleton() {
// Exists only to defeat instantiation.
}
}
然后你就可以直接使用了:
Singleton singleton = Singleton.INSTANCE;
singleton.dothis();
singleton.dothat();
...
上面产生单例的方法都是静态的,可以使用动态的方式吗?
使用register机制来动态完成单例的实例化。动态化我们首先想到了什么?对了,是反射。
import java.util.HashMap;
import org.apache.log4j.Logger;
public class Singleton {
private static HashMap map = new HashMap();
private static Logger logger = Logger.getRootLogger();
protected Singleton() {
// Exists only to thwart instantiation
}
public static synchronized Singleton getInstance(String classname) {
Singleton singleton = (Singleton)map.get(classname);
if(singleton != null) {
logger.info("got singleton from map: " + singleton);
return singleton;
}
try {
singleton = (Singleton)Class.forName(classname).newInstance();
}
catch(ClassNotFoundException cnf) {
logger.fatal("Couldn‘t find class " + classname);
}
catch(InstantiationException ie) {
logger.fatal("Couldn‘t instantiate an object of type " + classname);
}
catch(IllegalAccessException ia) {
logger.fatal("Couldn‘t access class " + classname);
}
map.put(classname, singleton);
logger.info("created singleton: " + singleton);
return singleton;
}
}
为了更好的复用代码,我们该怎么做呢?封装!
import java.util.HashMap;
import org.apache.log4j.Logger;
public class SingletonRegistry {
public static SingletonRegistry REGISTRY = new SingletonRegistry();
private static HashMap map = new HashMap();
private static Logger logger = Logger.getRootLogger();
protected SingletonRegistry() {
// Exists to defeat instantiation
}
public static synchronized Object getInstance(String classname) {
Object singleton = map.get(classname);
if(singleton != null) {
return singleton;
}
try {
singleton = Class.forName(classname).newInstance();
logger.info("created singleton: " + singleton);
}
catch(ClassNotFoundException cnf) {
logger.fatal("Couldn‘t find class " + classname);
}
catch(InstantiationException ie) {
logger.fatal("Couldn‘t instantiate an object of type " +
classname);
}
catch(IllegalAccessException ia) {
logger.fatal("Couldn‘t access class " + classname);
}
map.put(classname, singleton);
return singleton;
}
}
封装完成后,我们可以使用了。
import java.util.HashMap;
import org.apache.log4j.Logger;
public class Singleton {
protected Singleton() {
// Exists only to thwart instantiation.
}
public static Singleton getInstance() {
return (Singleton)SingletonRegistry.REGISTRY.getInstance(classname);
}
}
可是有很多护士给宝贝护理,怎么保证我们家的宝宝得到照顾呢?保证一个护士负责一个婴儿就ok了
护士classloader 婴儿instance
private static Class getClass(String classname)
throws ClassNotFoundException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if(classLoader == null)
classLoader = Singleton.class.getClassLoader();
return (classLoader.loadClass(classname));
}
}
import org.apache.log4j.Logger;
public class Singleton implements java.io.Serializable {
public static Singleton INSTANCE = new Singleton();
protected Singleton() {
// Exists only to thwart instantiation.
}
private Object readResolve() { //保证包裹的检查返回同一种情况。
return INSTANCE;
}
}
参考:
http://www.javaworld.com/article/2073352/core-java/simply-singleton.html
标签:load tin private efault com alac 宝贝 registry sts
原文地址:https://blog.51cto.com/15015181/2556815