package com.yukiyama.pattern.creation;
/**
* 单例模式
*/
public class SingletonDemo {
public static void main(String[] args) {
SingletonSimple s1 = SingletonSimple.getInstance();
SingletonSimple s2 = SingletonSimple.getInstance();
// 输出“true”,说明s1与s2是同一个实例
System.out.println(s1 == s2);
SingletonHungry s3 = SingletonHungry.getInstance();
SingletonHungry s4 = SingletonHungry.getInstance();
// 输出“true”,说明s3与s4是同一个实例
System.out.println(s3 == s4);
Singleton s5 = Singleton.getInstance();
Singleton s6 = Singleton.getInstance();
// 输出“true”,说明s3与s4是同一个实例
System.out.println(s5 == s6);
}
}
/**
* 饿汉模式
* 在类加载时创建常量化实例,不存在多线程导致可能出现多个实例的问题
*/
class SingletonHungry{
// 在定义SingletonHungry类型的属性时直接实例化,类内可以访问private构造器
private static final SingletonHungry instance = new SingletonHungry();
// 将构造器声明为private,外部无法用new获取
private SingletonHungry() {}
// 外部通过一个public的getInstance()方法获取该类实例
public static SingletonHungry getInstance() {
return instance;
}
}
/**
* 懒汉模式
* 非线程安全版
*/
class SingletonSimple {
private static SingletonSimple instance;
// 将构造器声明为private,外部无法用new获取
private SingletonSimple() {}
// 外部通过一个public的getInstance()方法获取该类实例
public static SingletonSimple getInstance() {
// 每次获取前判断该类实例是否已存在,若无则new一个
if (instance != null) {
instance = new SingletonSimple();
}
return instance;
}
}
/**
* 多线程下的双锁检测(Double-Check Locking)单例
* 懒汉模式
*/
class Singleton{
// 以volatile修饰
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
// 第一次判断的目的是避免每次getInstance()都加锁
// 若已经存在实例,直接返回
if(instance == null) {
synchronized (Singleton.class) {
// 再次判断是防止两个线程在instance==null时
// 同时进入第一个if内,由于加锁,其中一个先new了
// 实例,此时必须再判断一次防止第二个也new一个实例
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}