【java单例模式详解】

单例模式

单例模式是java的创建型模式之一。
定义:单例模式能够防止频繁创建和销毁全局使用的类实例的问题,该模式确保一个类只有一个实例,并提供一个全局访问点来访问该实例。

特点

  • 1、单例类只能有一个实例;
  • 2、单例类只能自己创建自己的唯一实例;
  • 3、保证其他类对象能访问该实例。

单例模式的实现方式有多种:懒汉式、饿汉式、双重校验锁、静态内部类、枚举。

下面依次介绍单例模式的不同方式实现:

懒汉式

懒汉式即创建实例之后懒得初始化,等到方法使用时再初始化。
优点:第一次调用时才加载,防止内存浪费;
缺点:加锁影响效率

public class Singleton {
	//static关键字确保在所有调用中共享同一实例
    private static Singleton instance;
    //其他类无法创建本类实例
    private Singleton (){}  
  	//保证能全局访问,去掉锁就变成线程不安全的懒汉式
    public static synchronized Singleton getInstance() {
    	//实例在第一次请求时才创建(延迟加载)
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}

饿汉式

优缺点与懒汉式相反:不需要加锁,效率高;类加载时就创建单例实例,浪费内存。

public class Singleton {
	//在类加载时就创建单例实例
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}

双重检验锁

优点:使用双锁机制,保证线程安全时还能保持高性能。
原理:使用volatile关键字防止指令重排序导致的线程安全问题,同时只在第一次初始化实例的时候加synchronized锁,后续调用不需要加锁,相比懒汉式每次调用实例都加锁大大提高了效率。

public class Singleton {
	// volatile 关键字确保实例的可见性和有序性
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) { 	//第一次检查
        synchronized (Singleton.class) {
            if (singleton == null) {	//第二次检查
            	//延迟加载
                singleton = new Singleton();  
            }  
        }  
    }  
    return singleton;  
    }  
}

静态内部类

这种方式只适用于静态域的情况,能达到双检锁方式一样的功效。
原理:只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance。由于静态内部类只有第一次使用时才会被加载(类加载机制),也就无需检查实例。

public class Singleton {  
	// 静态内部类,只有在第一次使用时才会被加载
    private static class SingletonHolder {  
    private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    // 提供全局访问点,通过内部类加载实现懒加载和线程安全
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE;  
    }  
}

枚举

最简洁,自动支持序列化机制,绝对防止多次实例化。
原理:枚举类型的每一个实例都是 public static final 的,枚举类型的构造方法在类加载时被调用,并且每个枚举常量只被初始化一次。

public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值