本主曾看到一个反问句?你会单利模式么?单利模式真那么简单么?
答案是:单例模式很难,注意点很多,难到本主头晕眼花。哈哈。
下面本主根据前辈文章做出的总结:
问题1.单例模式是什么?它为什么存在?
答:单例模式是一种在jvm中使目标对象只有一个实例存在;
那么它的作用就显而易见了:a).减去了大对象的创建开销,b).省去了new,降低了对内存堆栈的使用率,减轻GC压力
问题2.单例模式到底怎么写?
答:
/*持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载*/
private static Singleton instance=null;
/*私有化构造器,防止被实例*/
private Singleton() {
}
/*静态工程方法,创建实例*/
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
private static Singleton instance=null;
/*私有化构造器,防止被实例*/
private Singleton() {
}
/*静态工程方法,创建实例*/
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
/* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */
public Object readResolve() {
return instance;
}
问题3.如上所述,如果在兵法情况下呢,还能运行么?
答:不能,单例出来的很有可能是个null,原因请查阅:jvm创建对象的过程,你会发现。
问题4.那怎么写呢?
答:
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
问题5.给方法加了一把锁,那么也就是每次调用getInstance() 方法,都要给其返回的对象加一把锁,这样性能上是否会降低?
答:那肯定是会降低性能的
问题6.那该怎么设计呢?
答:只有当第一次创建对象时需要加锁,所以设计如下
public static Singleton getInstance() {
if (instance == null) {
synchronized (instance) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
问题7:上述写法真的没有问题么?
答:不,是存在很大问题的。如果在并发情况下, instance = new Singleton(); 在创建引用完毕,初始化内存空间实例之前,另一个线程闯入了呢,还是会出现创建出null对象的可能行。
问题8:那到底该怎么设计呢?
答:
/* 此处使用一个内部类来维护单例 */
private static class SingletonFactory {
private static Singleton instance = new Singleton();
}
/* 获取实例 */
public static Singleton getInstance() {
return SingletonFactory.instance;
}
问题9:这样不就解决了,可是这样真的好么?
答:
其实说它完美,也不一定,如果在构造函数中抛出异常,实例将永远得不到创建,也会出错。所以说,十分完美的东西是没有的,我们只能根据实际情况,选择最适合自己应用场景的实现方法。也有人这样实现:因为我们只需要在创建类的时候进行同步,所以只要将创建和getInstance()分开,单独为创建加synchronized关键字,也是可以的:
private static synchronized void syncInit() {
if (instance == null) {
instance = new SingletonTest();
}
}
public static SingletonTest getInstance() {
if (instance == null) {
syncInit();
}
return instance;
}
其思想就是在编译时创建好单例
本文为本主观大神4835830后而加,请各位大侠指导,相关资料请查阅大神http://download.youkuaiyun.com/detail/zhangerqing/4835830
注:本文代码转自csdn:4835830
如有侵权,请联系本人。