欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

漫说单例模式--宝宝成长记 你真的了解了吗?

发布时间:2025/4/5 编程问答 62 豆豆
生活随笔 收集整理的这篇文章主要介绍了 漫说单例模式--宝宝成长记 你真的了解了吗? 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

1. 你就是单例

你呱呱落地到这个世界的时候,这就是单例的产生,你是世界上唯一无二的存在。

 

此时,你是父辈、祖辈的宝贝。他们都想和你亲近。

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;} }

 

2. 竞争的产生

    很多人想报你和你亲近,可你只有一个呀,这就产生了矛盾,这就需要你来控制谁可以来抱你了。这就需要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。

3. 太复杂了,扛不住了,那就简单一点吧

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();...

4. 上面产生单例的方法都是静态的,可以使用动态的方式吗?

    使用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);} }

5. 如果有很多小孩,医院是如何管理的呢?

可是有很多护士给宝贝护理,怎么保证我们家的宝宝得到照顾呢?保证一个护士负责一个婴儿就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));} }

6. 如何给婴儿包被褥呢?当脱掉一件后如果被包裹了两层就,不好了。为了避免这种情况,就需要检查包裹的效果了。

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;} }

 

 参考:

1. http://en.wikipedia.org/wiki/Singleton_pattern

2. http://www.javaworld.com/article/2073352/core-java/simply-singleton.html

3. 注意,以上图片均来自互联网,不一一标注了。

 

 

转载于:https://www.cnblogs.com/davidwang456/p/3642696.html

总结

以上是生活随笔为你收集整理的漫说单例模式--宝宝成长记 你真的了解了吗?的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。