设计模式—单例模式
程序员文章站
2023-12-28 13:24:10
...
单例模式
核心作用
保证一个类只有一个实例,并且 提供一个访问该实例的全局访问点
优点
- 由于单例模式只生成一个实例,减少了系统性能开销
- 单例模式可以在系统设置全局的访问点,优化共享资源访问
常见的五种单例模式实现方式
- 饿汉式:(线程安全,调用效率高,不能延时加载)
- 懒汉式:(线程安全,调用效率不高,可以延时加载)
- DCL懒汉式:(由于JVM底层内部模型原因,偶尔会出现问题,不建议使用)
- 饿汉式改进:静态内部类式(线程安全,调用效率高,可以延时加载)
- 枚举单例:(线程安全,调用效率高,不能延时加载)
饿汉式
/**
* 饿汉式单例
*/
public class SingletonDemo01 {
// 私有化构造器
private SingletonDemo01(){
}
// 类初始化时就加载该对象
private static SingletonDemo01 instance = new SingletonDemo01();
// 提供获取该对象的方法,没有synchronized,效率高
public static SingletonDemo01 getInstance(){
return instance;
}
}
class SingletonDemo01Test{
public static void main(String[] args) {
SingletonDemo01 instance1 = SingletonDemo01.getInstance();
SingletonDemo01 instance2 = SingletonDemo01.getInstance();
System.out.println(instance1 == instance2); // true
}
}
懒汉式
/**
* 懒汉式
*/
public class SingletonDemo02 {
// 私有化构造器
private SingletonDemo02(){
}
// 类初始化时不加载该对象
private static SingletonDemo02 instance;
// 提供获取该对象的方法,有synchronized,效率较低
public static synchronized SingletonDemo02 getInstance(){
if(instance == null){
instance = new SingletonDemo02();
}
return instance;
}
}
class SingletonDemo02Test{
public static void main(String[] args) {
SingletonDemo02 instance1 = SingletonDemo02.getInstance();
SingletonDemo02 instance2 = SingletonDemo02.getInstance();
System.out.println(instance1 == instance2); // true
}
}
DCL懒汉式
/**
* DCL懒汉式
*/
public class SingletonDemo03 {
// 私有化构造器
private SingletonDemo03(){
}
// 类初始化时不加载该对象
private volatile static SingletonDemo03 instance;
// 提供获取该对象的方法,有synchronized,效率较低
public static SingletonDemo03 getInstance(){
if(instance == null){
synchronized (SingletonDemo03.class){
if(instance == null){
instance = new SingletonDemo03();
}
}
}
return instance;
}
}
class SingletonDemo03Test{
public static void main(String[] args) {
SingletonDemo03 instance1 = SingletonDemo03.getInstance();
SingletonDemo03 instance2 = SingletonDemo03.getInstance();
System.out.println(instance1 == instance2); // true
}
}
饿汉式改进
/**
* 饿汉式改进,静态内部类实现
*/
public class SingletonDemo04 {
private SingletonDemo04(){
}
private static class InnerClass{
private static final SingletonDemo04 instance = new SingletonDemo04();
}
public static SingletonDemo04 getInstance(){
return InnerClass.instance;
}
}
class SingletonDemo04Test{
public static void main(String[] args) {
SingletonDemo04 instance1 = SingletonDemo04.getInstance();
SingletonDemo04 instance2 = SingletonDemo04.getInstance();
System.out.println(instance1 == instance2); // true
}
}
反射机制可以破坏该单例
class SingletonDemo04Test{
public static void main(String[] args) throws Exception {
SingletonDemo04 instance1 = SingletonDemo04.getInstance();
Constructor<SingletonDemo04> declaredConstructor = SingletonDemo04.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
SingletonDemo04 instance2 = declaredConstructor.newInstance();
System.out.println(instance1 == instance2); // false
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
}
}
枚举单例
/**
* 枚举单例
*/
public enum SingletonDemo05 {
INSTANCE;
public SingletonDemo05 getInstance(){
return INSTANCE;
}
}
class SingletonDemo05Test{
public static void main(String[] args) {
SingletonDemo05 instance1 = SingletonDemo05.INSTANCE;
SingletonDemo05 instance2 = SingletonDemo05.INSTANCE;
System.out.println(instance1 == instance2); //true
}
}