计模式之单件模式(单例模式)
单件模式是最简单的设计模式啦!(窝感觉~~) 有一些对象我们只需要一个,例如:线程池(threadpool),缓存(cache),充当打印机,显卡等设备的驱动程序的对象。 这些类对象只能有一个实例,多了会出现一些问题。 全局变量缺点:必须在一开始就创建对象,浪费资源。 只创建一个对象的方法:首先将构造函数私有,这样这个类就不会随意的创建了。然后为类创建一个产生实例变量的方法。 单件模式的实现: </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> Singleton uniqueSingleton;
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> Singleton() { }
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> Singleton getInstance() {
</span><span style="color: #0000ff;">if</span> (uniqueSingleton == <span style="color: #0000ff;">null</span><span style="color: #000000;">) {
uniqueSingleton </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Singleton();
}
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> uniqueSingleton;
}
} 如果不需要这个实例,它就永远不会被产生,这就是“延迟实例化”(lazy-instantiaze) 单件模式:确保一个类只有一个实例,并提供一个全局访问点。 但是在多线程情况下,会产生一些问题,如下图情况: 呀~~产生了两个对象! 于是在多线程的时候 需要把getInstance()函数变成同步方法啦 (uniqueSingleton == =
但是……同步会降低性能…… 1.如果getInstance()方法的性能对应用程序不是很关键,就这样就可以了。 2.如果程序总是创建并使用单件实例,或者在创建或运行时方面的负担不太繁重,可以一开始就创建实例。 </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> Singleton uniqueSingleton = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Singleton();
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> Singleton() { }
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> Singleton getInstance() {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> uniqueSingleton;
}
} 3.用双重加锁,在getInstance()中减少使用同步 </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">volatile</span> <span style="color: #0000ff;">static</span> Singleton uniqueSingleton; <span style="color: #008000;">//</span><span style="color: #008000;"> volatile关键字确保 当uniqueSingleton被初始化后
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 多个线程正确的处理uniqueSingleton变量</span>
<span style="color: #0000ff;">private</span><span style="color: #000000;"> Singleton() { }
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> Singleton getInstance() {
</span><span style="color: #0000ff;">if</span> (uniqueSingleton == <span style="color: #0000ff;">null</span>) { <span style="color: #008000;">//</span><span style="color: #008000;"> 检查实例 如果不存在就进入同步区</span>
<span style="color: #0000ff;">synchronized</span> (Singleton.<span style="color: #0000ff;">class</span><span style="color: #000000;">) {
</span><span style="color: #0000ff;">if</span> (uniqueSingleton == <span style="color: #0000ff;">null</span>) { <span style="color: #008000;">//</span><span style="color: #008000;"> 进入区块后 在检查一次 如果仍然是null 才创建实例</span>
uniqueSingleton = <span style="color: #0000ff;">new</span> Singleton(); <span style="color: #008000;">//</span><span style="color: #008000;"> 注意:只有第一次才彻底执行这里的代码</span>
<span style="color: #000000;"> } } } 4. 通过枚举实现单例模式 通过内部静态enum的方法来实现,因为JVM会保证enum不能被反射并且构造器方法只执行一次。 </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> EnumSingleton getInstance(){
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> Singleton.INSTANCE.getInstance();
}
</span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">enum</span><span style="color: #000000;"> Singleton{
INSTANCE;
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> EnumSingleton singleton;
</span><span style="color: #008000;">//</span><span style="color: #008000;">JVM会保证此方法绝对只调用一次</span>
<span style="color: #0000ff;">private</span><span style="color: #000000;"> Singleton(){
singleton </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> EnumSingleton();
}
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> EnumSingleton getInstance() {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> singleton;
}
}
} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |