直接编写单例模式的代码
- 要点
package singleton;
/**
* 饿汉式:
* 在类初始化时直接创建实例对象,不管你是否需要这个对象都会创建
*
* (1)构造器私有化
* (2)自行创建,并且用静态变量保存
* (3)向外提供这个实例
* (4)强调这是一个单例,我们可以使用final修饰
*/
public class Singleton1 {
public static final Singleton1 INSTANCE = new Singleton1();
private Singleton1() {
}
}
枚举类型:
package singleton;
/**
* 枚举类型,表示该类型的对象是有限个
* 我们可以限定为一个,就成了单例
*/
public enum Singleton2 {
INSTANCE
}
静态代码块饿汉式:
package singleton;
import java.io.IOException;
import java.util.Properties;
public class Singleton3 {
public static final Singleton3 INSTANCE;
/**
* 适用于创建对象需要从文件中读取信息时
*/
static {
try {
Properties properties = new Properties();
properties.load(Singleton3.class.getClassLoader().getResourceAsStream("single.properties"));
INSTANCE = new Singleton3(properties.getProperty("info"));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Singleton3(String info) {
}
}
线程不安全,适用于单线程
package singleton;
/**
* 懒汉式:
* 延迟创建实例对象
* <p>
* (1)构造器私有化
* (2)用静态变量保存唯一的实实例
* (3)提供一个静态方法,获取这个实例对象
*/
public class Singleton4 {
private static Singleton4 instance;
private Singleton4() {
}
public static Singleton4 getInstance() {
if (instance == null) {
instance = new Singleton4();
return instance;
} else {
return instance;
}
}
}
使用于多线程的版本
package singleton;
/**
* 懒汉式:
* 延迟创建实例对象
* <p>
* (1)构造器私有化
* (2)用静态变量保存唯一的实实例
* (3)提供一个静态方法,获取这个实例对象
*/
public class Singleton5 {
private static Singleton5 instance;
private Singleton5() {
}
public static Singleton5 getInstance() {
if (instance == null) {
synchronized (Singleton5.class) {
// 加锁后 使用于多线程
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Singleton5();
return instance;
}
} else {
return instance;
}
}
}
终极写法 (使用内部类)
package singleton;
/**
* 在内部类被加载和初始化时,才创建INSTANCE对象
* 静态内部类不会随着外部类的加载和初始化而初始化,它是要单独去加载与初始化的
* 因为是在内部类加载和初始化时创建的,所以是线程安全的
*/
public class Singleton6 {
private Singleton6() {
}
private static class Inner {
private static final Singleton6 INSTANCE = new Singleton6();
}
public static Singleton6 getInstance() {
return Inner.INSTANCE;
}
}