您的位置:首页 > 其它

设计模式学习笔记(五)--单件模式

2017-12-25 16:52 435 查看
[同系列文章]

1.设计模式学习笔记(一)- -策略模式

2.设计模式学习笔记(二)- -观察者模式

3.设计模式学习笔记(三)- –装饰者模式

4.设计模式学习笔记(四)- –工厂模式

这个这个,疯狂打CALL,应该是最爽最最常用的一个模式了,小巧玲珑喔~~

文末附上传说中的最稳的单件模式写法:)

推荐使用:(饿汉式):延迟实例化1.0/2.0静态内部类,有多线程需求用:双重检查加锁

经典的单例模式 写法:(懒汉式,线程不安全):

public class Singleton{
private static Singleton uniqueInstance;
private Singleton(){}
public static Singleton getInstance(){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}


单例模式确保一个类只有一个实例,并提供一个全局访问点。

处理多线程,要用线程保护,将getInstance()变成同步(synchronized)方法,解决多线程灾难,以下是针对于多线程的单例的优化:

(懒汉式,线程安全):

public class Singleton{
private static Singleton uniqueInstance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}


但是这样子写,每次进入都会调用同步的方法,降低性能。

我们做出优化呗,继续对多线程进行改善,书中有多种思路,如下:

程序受得了同步的折腾2333,getInstance()的性能对应用不是很关键,那么就什么都不做。同步一个方法,可能会给程序的执行效率下降100倍,切记:不要被应用在频繁运行的地方;

使用“急切”创建实例,而不用延迟实例化的做法

如果应用程序总是创建并使用单件实例,或者创建和运行时方面的负担不太重,可以提前创建此单件:

(饿汉式):延迟实例化1.0:

public class Singleton{
private static Singleton uniqueInstance = new Singleton();
private Singleton(){}
public static synchronized Singleton getInstance(){
return uniqueInstance;
}
}


(饿汉式):延迟实例化2.0: (PS:和1.0差不多的,都是在类初始化即实例化instance)

public class Singleton {
private Singleton uniqueInstance = null;
static {
uniqueInstance = new Singleton();
}
private Singleton (){}
public static Singleton getInstance() {
return uniqueInstance ;
}
}


JVM在加载这个类时,马上就创建这个唯一的单件实例。关于JVM的承诺:保证在任何线程访问uniqueInstance静态变量之前,一定先创建该实例。

补充一个~~~>(静态内部类):

public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}


再补充一个~~~>(枚举):

public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}


Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。

3.用“双重检查加锁”,在getInstance()中减少使用同步

思路:先检查是否已经创建实例,如果没有,再同步。

PS:使用volatile关键字,它确保uniqueInstance 变量被初始化时,多个线程正确的处理uniqueInstance 变量;不适用于1.4之前的jdk。

public class Singleton{
private volatile static Singleton uniqueInstance;
private Singleton(){}
public static Singleton getInstance(){
if(uniqueInstance == null){
synchronized(Singleton.class){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}


反序列化

public class Singletonimplements Serializable {

private static volatile SingletonsSoleInstance;
private Singleton(){

//Prevent form the reflection api.
if (sSoleInstance != null){
throw new RuntimeException("Use getInstance() method to get the single instance of this class.");
}
}

public static SingletongetInstance() {
if (sSoleInstance == null) { //if there is no instance
a751
available... create new one
synchronized (Singleton.class) {
if (sSoleInstance == null)  sSoleInstance = new Singleton();
}
}

return sSoleInstance;
}

//Make singleton from serialize and deserialize operation.
protected Singleton readResolve() {
return getInstance();
}
}


参考:

这篇博客写得很齐全啦,设计模式 单例模式 优雅的单例模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式 singleton