Singleton
饿汉模式
public class Sigleton {
//饿汉模式 outInstance是私有的
private static Sigleton ourInstance = new Sigleton();
/**
* 此实现是线程安全的 JVM在加载此类时,因为对于static属性的初始化只能由一个线程执行且仅执行一次
* 缺点:instance在类装载时就实例化 这时候初始化instance显然没有达到lazy loading的效果
* @return
*/
public static Sigleton getInstance() {
return ourInstance;
}
//把构造函数声明为private 客户对象无法创建该实例
private Sigleton() {
}
}
懒汉模式
public class Sigleton2 {
//懒汉模式(需要时才实例化对象)
private static Sigleton2 instance;
/**
* 线程不安全 原因:getInstance在高并发环境下可能会被同时调用,导致if(instance==null)判断就不靠谱
* @return
*/
// public static Sigleton2 getInstance() {
// if (instance == null) {
// instance = new Sigleton2();
// }
// return instance;
// }
/**
* 解决方法:添加synchornized关键字
* 缺点:性能降低
* @return
*/
public static synchronized Sigleton2 getInstance() {
if (instance == null) {
instance = new Sigleton2();
}
return instance;
}
private Sigleton2(){
}
}
双重校验锁
public class DoubleCheckSingleton {
//此方法需要在Java 5及以上的版本才能运行 volatile关键字在Java5引入
public volatile static DoubleCheckSingleton instance = null;
private DoubleCheckSingleton(){}
public static DoubleCheckSingleton getInstance() {
if (instance == null) { //检查实例是否创建 如果没有把 DoubleCheckSingleton.class设置为同步
synchronized (DoubleCheckSingleton.class) {
if (instance == null) { //double check
instance = new DoubleCheckSingleton();
}
}
}
return instance;
}
}
静态内部类
public class StaticSingleton {
private static class SingletonHolder {
private static final StaticSingleton INSTANCE = new StaticSingleton();
}
private StaticSingleton (){}
//这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程
public static final StaticSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
Singleton的序列化
如果单例类实现了Serializable接口,默认情况下,每次反序列化总会创建一个新的实例对象。
解决方法:重写readResolve()方法,直接返回单例对象
package Sigleton;
import java.io.Serializable;
/**
* Created by Zz on 2017/5/3 0003.
*/
public class Sigleton implements Serializable{
private static final long serialVersionUid = -6012841243252L;
//饿汉模式 outInstance是私有的
private static Sigleton ourInstance = new Sigleton();
/**
* 此实现是线程安全的 JVM在加载此类时,因为对于static属性的初始化只能由一个线程执行且仅执行一次
* 缺点:instance在类装载时就实例化 这时候初始化instance显然没有达到lazy loading的效果
* @return
*/
public static Sigleton getInstance() {
return ourInstance;
}
//把构造函数声明为private 客户对象无法创建该实例
private Sigleton() {
}
private Object readResolve(){
return ourInstance;
}
}
作者:张金龙
链接:Java设计模式–单例类