单例模式
介绍
主要目的保证一个类只有一个实例。防止一个全局使用的类频繁地创建与销毁。
优点
1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
2、避免对资源的多重占用(比如写文件操作)。
缺点
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
实现
懒汉式线程不安全的
首先懒汉式指的是每次get方法的时候才进行实例初始化。其次之所以说这种方式不是线程安全的主要的是get方法并没有任何并发控制的操作。所以严格意义上来说这个可能会在并发情况下导致创建了多个实例。
public class SingletonPattern {
private static SingletonPattern singletonPattern;
private SingletonPattern() {
}
public static SingletonPattern getSingletonPattern() {
//如果singletonPattern是null则进行新建
if (singletonPattern == null) {
singletonPattern = new SingletonPattern();
}
return singletonPattern;
}
}
懒汉式线程安全的
相比较于上边的方法在get方法上增加了synchronized确保了单例。但是懒汉式的好处在于使用的时候才进行实例化。避免内存浪费。
public class SingletonPattern {
private static SingletonPattern singletonPattern;
private SingletonPattern() {
}
//他和线程不安全的主要区别在于将get方法进行了synchronized修饰保证线程安全。导致效率的降低
public static synchronized SingletonPattern getSingletonPattern() {
//如果singletonPattern是null则进行新建
if (singletonPattern == null) {
singletonPattern = new SingletonPattern();
}
return singletonPattern;
}
}
饿汉式
饿汉式首先表明就是每次类被加载的时候就会被实例化。优点是不需要使用锁进行枷锁。
public class SingletonPattern {
//不管需要不需要都是直接将对象进行实例化
private static SingletonPattern singletonPattern = new SingletonPattern();
private SingletonPattern() {
}
public static SingletonPattern getSingletonPattern() {
return singletonPattern;
}
}
双重锁校验
这个方法相对来说比较好理解。volatile关键字保证对象的并发。synchronized关键字保证get创建方法的并发控制。个人比较喜欢这种方式吧。
public class SingletonPattern {
//使用volatile进行修饰确保线程安全。
private volatile static SingletonPattern singletonPattern;
private SingletonPattern() {
}
public static SingletonPattern getSingletonPattern() {
if (singletonPattern == null) {
synchronized (SingletonPattern.class) {
//synchronized获取到锁可能是别人已经做过了初始化工作。所以
if (singletonPattern == null) {
singletonPattern = new SingletonPattern();
}
}
}
return singletonPattern;
}
}
静态内部类
这种方法也能保证线程安全问题。ClassLoader机制对于类只加载一次。它实现了懒加载方式SingletonHolder类只有在调用了get方法的时候才初始化。
public class SingletonPattern {
//使用内部类借用classLoader原理使SingletonHolder只被初始化一次
private static class SingletonHolder {
private static final SingletonPattern INSTANCE = new SingletonPattern();
}
private SingletonPattern() {
}
public static final SingletonPattern getInstance() {
return SingletonHolder.INSTANCE;
}
}
枚举
JDK 版本:JDK1.5 起
是否 Lazy 初始化:否
描述:告辞这个方法我也不会。抄个代码溜了。枚举似乎个人不常用。
public enum SingletonPattern {
INSTANCE;
public void whateverMethod() {
}
}