设计模式之单例模式

2018-02-08  本文已影响0人  有没有口罩给我一个

单例模式

定义:保证一个类在软件系统中仅有一个实例,并对外提供一个访问它的接口;


单例模式

单例模式有两种,一种是饿汉模式,另一种是懒汉模式,有6中实现方式;

饿汉模式:
public class Singleton {
private static final Singleton ourInstance = new Singleton();
public static Singleton getInstance() {
    return ourInstance;
}
private Singleton() {
  }
}

这种方式就是基于来加载机制,避免了多线程的同步问题,但是没有达到懒加载的效果,如果没有使用该实例,旧货造成内存浪费;

懒汉模式

1、线程不安全

public class Singleton {
private static Singleton ourInstance;

public static Singleton getInstance() {
    if (ourInstance == null) {
        ourInstance = new Singleton();
    }
    return ourInstance;
}

private Singleton() {
}
}

2、线程安全

public class Singleton {
private static Singleton ourInstance;

public static synchronized Singleton getInstance() {
    if (ourInstance == null) {
        ourInstance = new Singleton();
    }
    return ourInstance;
}

private Singleton() {
}
 }

3、双重检验锁

public class Singleton {
private volatile static Singleton ourInstance;

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

private Singleton() {
}
}

4、静态内部类

public class Singleton {
public static Singleton getInstance() {
    return SingletonHolder.ourInstance;
}

private static class SingletonHolder {
    private static final Singleton ourInstance = new Singleton();
}

private Singleton() {
}
}

第一次加载Singleton时并不会初始化Singleton实例,只有第一次调用getInstance方法时虚拟机加载SingletonHolder 并初始化Singleton 实例,这样不仅能保证线程安全,也具有懒加载和唯一性,这种方式是比较推荐的;

最后说一下单例模式需要注意的一些问题:

1、保证唯一性;
2、线程安全;
3、反射影响;
4、反序列化;
5、volatile保证有序性;

public class Singleton {
private volatile static Singleton ourInstance;

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

private Singleton() {
    if (ourInstance != null) {
        throw new RuntimeException("Singleton only create one instance");
    }
}

private Object readResolve() throws ObjectStreamException {
    return ourInstance;
}
}
上一篇 下一篇

猜你喜欢

热点阅读