原文地址:http://news.bangkaow.com/news/20100919/56701.html 1、最简单的实现 public class SingletonClass { private static final SingletonClass instance = new SingletonClass(); public static SingletonClass getInstance() { return instance; } private SingletonClass() { } } 缺点:无论这个类是否被使用,都会创建一个instance对象。 2、延迟加载 public class SingletonClass { private static SingletonClass instance = null; public static SingletonClass getInstance() { if(instance == null) { instance = new SingletonClass(); } return instance; } private SingletonClass() { } } 局限:多线程下的同步问题。 3、同步 public class SingletonClass { private static SingletonClass instance = null; public synchronized static SingletonClass getInstance() { if(instance == null) { instance = new SingletonClass(); } return instance; } private SingletonClass() { } } 缺点:存在性能问题,每次获取实例对象都要进入同步块。 4、DCL(Doble-Checked Locking) public class SingletonClass { private static SingletonClass instance = null; public static SingletonClass getInstance() { if (instance == null) { synchronized (SingletonClass.class) { if (instance == null) { instance = new SingletonClass(); } } } return instance; } private SingletonClass() { } } 缺陷:创建一个变量需要哪些步骤呢?一个是申请一块内存,调用构造方法进行初始化操作,另一个是分配一个指针指向这块内存。这两个操作谁在前谁在后呢?JVM规范并没有规定。那么就存在这么一种情况,JVM是先开辟出一块内存,然后把指针指向这块内存,最后调用构造方法进行初始化。 下面我们来考虑这么一种情况:线程A开始创建SingletonClass的实例,此时线程B调用了getInstance()方法,首先判断instance是否为null。按照我们上面所说的内存模型,A已经把instance指向了那块内存,只是还没有调用构造方法,因此B检测到instance不为 null,于是直接把instance返回了——问题出现了,尽管instance不为null,但它并没有构造完成,就像一套房子已经给了你钥匙,但你并不能住进去,因为里面还没有收拾。此时,如果B在A将instance构造完成之前就是用了这个实例,程序就会出现错误了! 5、解决方案 5.1、volatile public class SingletonClass { private volatile static SingletonClass instance = null; public static SingletonClass getInstance() { if (instance == null) { synchronized (SingletonClass.class) { if(instance == null) { instance = new SingletonClass(); } } } return instance; } private SingletonClass() { } } 5.2、inner class(推荐) public class SingletonClass { private static class SingletonClassInstance { private static final SingletonClass instance = new SingletonClass(); } public static SingletonClass getInstance() { return SingletonClassInstance.instance; } private SingletonClass() { } } |
单例模式
最新推荐文章于 2024-07-23 16:12:40 发布