/**
* 饿汉式 在类初始化时直接创建对象,不存在线程安全问题,不管你是否需要这个对象都会创建
* <p>
* 1. 构造器私有化
* 2. 自行创建,并且用静态变量保存
* 3. 向外提供这个实例
* 4. 强调这是一个单例,我们可以用final修饰,不能改变引用,可以改变属性。
*
* @author yuan
*/
public class Singleton1 {
public static final Singleton1 INSTANCE = new Singleton1();
private static Date date = new Date();
private Singleton1() {
}
}
/**
* 饿汉式
* <p>
* 枚举类型:表示该类型的对象是有限的几个
* 我们可以限定成一个,就成了单例
* <p>
* public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE };
* 实际上,这个声明定义的类型是一个类,它刚好有四个实例,在此尽量不要构造新对象。
* https://www.cnblogs.com/liaojie970/p/6474733.html
*
* @author yuan
*/
public enum Singleton2 {
/**
* 相当于 Singleton2 INSTANCE = new Singleton2()
* 反编译可以看到这个类的构造函数是私有的: private Singleton2() {}
*/
INSTANCE
}
package com.yuan.middleware.base.design.single;
import lombok.Data;
import java.io.IOException;
import java.util.Properties;
/**
* 饿汉式
* <p>
* 静态代码块饿汉式,也是线程安全的
* 适合于需要灵活初始化属性
*
* @author yuan
*/
@Data
public class Singleton3 {
public static final Singleton3 INSTANCE;
private String info;
static {
Properties pro = new Properties();
try {
//通过类加载器加载配置文件,需要特别注意文件路径否则NullPointerException
pro.load(Singleton3.class.getClassLoader().getResourceAsStream("single.properties"));
} catch (IOException e) {
throw new RuntimeException(e);
}
INSTANCE = new Singleton3(pro.getProperty("info"));
}
private Singleton3(String info) {
this.info = info;
}
}
package com.yuan.middleware.base.design.single;
/**
* 懒汉式
* 延迟创建这个实例对象
* 1. 构造器私有化
* 2. 用一个静态变量保存这个唯一的实例
* 3. 提供一个静态方法,获取这个实例对象
*
* @author yuan
*/
public class Singleton4 {
private static Singleton4 instance;
private Singleton4() {
}
/**
* 线程不安全
*
* @return
*/
public static Singleton4 getInstance() {
if (instance == null) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Singleton4();
}
return instance;
}
}
package com.yuan.middleware.base.design.single;
/**
* 懒汉式
* 延迟创建这个实例对象
* 1. 构造器私有化
* 2. 用一个静态变量保存这个唯一的实例
* 3. 提供一个静态方法,获取这个实例对象
*
* @author yuan
*/
public class Singleton5 {
private static Singleton5 instance;
private Singleton5() {
}
/**
* 线程安全
*
* @return
*/
public static Singleton5 getInstance() {
if (instance == null) {
synchronized (instance) {
if (instance == null) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Singleton5();
}
}
}
return instance;
}
}
package com.yuan.middleware.base.design.single;
/**
* 懒汉式
* 在内部类被加载和初始化时,才创建INSTANCE实例对象
* 静态内部类不会自动随着外部内的加载和初始化而初始化,它是需要单独去加载和初始化的
* 因为是在内部类加载和初始化时,创建的,因此是线程安全的
* <p>
* JVM必须确保一个类在初始化的过程中,如果是多线程需要同时初始化它,仅仅只能允许其中一个线程对其执行初始化操作,
* 其余线程必须等待,只有在活动线程执行完对类的初始化操作之后,才会通知正在等待的其他线程。
*
* @author yuan
*/
public class Singleton6 {
private Singleton6() {
}
private static class Inner {
private static final Singleton6 INSTANCE = new Singleton6();
}
public static Singleton6 getInstance() {
return Inner.INSTANCE;
}
}