Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点。
/**
* 测试饿汉式单例模式
*/
public class SingletonDemo1 {
//类初始化时,立即加载这个对象(没有延时加载的优势)。加载类时,天然的是线程安全的!
private static final SingletonDemo1 instance
= new SingletonDemo1();
private SingletonDemo1(){
}
//方法没有同步,调用效率高!
public static SingletonDemo1 getInstance(){
return instance;
}
}
/**
* 测试懒汉式单例模式
*/
public class SingletonDemo2 {
//类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)。
private static SingletonDemo2 instance;
private SingletonDemo2(){ //私有化构造器
}
//方法同步,调用效率低!
public static synchronized SingletonDemo2 getInstance(){
if(instance==null){
instance = new SingletonDemo2();
}
return instance;
}
}
(双重锁,可能与网上有差别)
/**
* 双重检查锁实现单例模式
*/
public class SingletonDemo3 {
// 定义一个静态私有变量(不初始化,不使用final关键字,
// 使用volatile保证了多线程访问时instance变量的可见性,
// 避免了instance初始化时其他变量属性还没赋值完时,被另外线程调用)
// 可以使用volatile关键字
private static SingletonDemo3 instance = null;
public static SingletonDemo3 getInstance() {
if (instance == null) {
SingletonDemo3 sc;
synchronized (SingletonDemo3.class) {
sc = instance;
if (sc == null) {
synchronized (SingletonDemo3.class) {
if (sc == null) {
sc = new SingletonDemo3();
}
}
instance = sc;
}
}
}
return instance;
}
private SingletonDemo3() {
}
}
/**
* 测试静态内部类实现单例模式
* 这种方式:线程安全,调用效率高,并且实现了延时加载!
*
*/
public class SingletonDemo4 {
private static class SingletonClassInstance {
private static final SingletonDemo4
instance = new SingletonDemo4();
}
private SingletonDemo4(){
}
//方法没有同步,调用效率高!
public static SingletonDemo4 getInstance(){
return SingletonClassInstance.instance;
}
}
/**
* 测试枚举式实现单例模式(没有延时加载)
*/
public enum SingletonDemo5 {
//这个枚举元素,本身就是单例对象!
INSTANCE;
//添加自己需要的操作!
public void singletonOperation(){
}
}
/**
* 测试懒汉式单例模式(如何防止反射和反序列化漏洞)
*/
public class SingletonDemo6 implements Serializable {
// 类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)。
private static SingletonDemo6 instance;
// 私有化构造器
private SingletonDemo6() {
// 抛异常
if (instance != null) {
throw new RuntimeException();
}
}
// 方法同步,调用效率低!
public static synchronized SingletonDemo6 getInstance() {
if (instance == null) {
instance = new SingletonDemo6();
}
return instance;
}
// 反序列化时,如果定义了readResolve()则直接返回此方法指定的对象。而不需要单独再创建新对象!
private Object readResolve() throws ObjectStreamException {
return instance;
}
}