1、简介
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(这种方法一般是静态的)
2、单例模式八种方式
- 饿汉式【静态常量】
- 饿汉式【静态代码块】
- 懒汉式【线程不安全】
- 懒汉式【线程安全,同步方法】
- 懒汉式【线程安全,同步代码块】
- 双重检查
- 静态内部类
-
3、单例模式注意事项和细节说明
单例模式保证了系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建和销毁的对象,使用单例模式可以提高系统性能
**
- 当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用new
- 单例模式使用的场景:
- 需要频繁的进行创建和销毁的对象
- 创建对象时耗时过多或者耗费资源过多(重量级对象)
- 不常用的对象,工具类对象
- 频繁访问数据库或文件的对象(例如:数据源,session工厂等)
- 单例模式在JDK中的Runtime类中使用到了(饿汉式)
4、八种单例设计模式
4.1 懒汉式:静态常量
4.1.1 步骤如下:
- 构造器私有化 (不能通过new得到对象)
**
- 类的内部创建对象 【定义一个常量对象】
**
- 向外面暴露一个静态的公共方法 getInstance()
4.1.2 代码实现
//单例模式 静态常量 饿汉式
public class Type1 {
public static void main(String[] args) {
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
//发现这两个实例的内存地址是相同的。
System.out.println(instance == instance2);//true
}
}
class Singleton{
//1.构造器私有化
private Singleton(){}
//2.本类内部创建对象实例 【在类的加载的时候就创建了对象实例】[静态常量]
private final static Singleton INSTANCE = new Singleton();
//3.提供一个静态的getInstance()方法
public static Singleton getInstance(){
return INSTANCE ;
}
}
4.1.3 优缺点:
- 优点:这种写法比较简单,就是在类装载的时候就完成了实例化,避免了线程同步问题。
- 缺点:在类装载的时候就完成了实例化,没有达到懒加载的效果,如果从始至终从未使用过这个对象,则会造成内存的浪费。
- 这种方式基于类加载机制避免了很多线程同步问题,不过,intstance在类装载时就实例化,在单例模式中大多数都是调用getInstance方法,但是导致类装载的原因有很多种,因此不能确定有其他的方式(或者其他的静态方法)导致类装载,这时初始化instance就没有达到懒加载的效果
- 结论:这种单例模式可用,但是有可能会造成内存泄漏
4.2 饿汉式:静态代码块
4.2.1 步骤如下:
- 构造器私有化 (不能通过new得到对象)
**
- 在静态代码块中创建单例对象
**
- 向外面暴露一个静态的公共方法 getInstance()
4.2.2 代码实现
class Singleton2{
//成员变量
private static Singleton2 instance;
//1.构造器私有化
private Singleton2(){}
//2.在静态代码块中创建对象,并复制给成员变量
static {
instance = new Singleton2();
}
//3.提供一个静态的getInstance()方法
public static Singleton2 getInstance(){
return instance;
}
}
4.2.3 饿汉式的静态代码块实现优缺点:
这种方式和上面的类似,只不过将类的实例化的过程放在了静态代码块中,也是在类加载的时候,就执行静态代码块中的代码,初始化类的实例,优缺点和上面是一样得
结论:这种单例模式可用,但是有可能会造成内存泄漏
4.3 懒汉式:线程不安全
4.3.1 步骤如下:
- 创建一个私有静态属性
- 构造器私有化
- 创建一个getInstance()静态方法,在使用到该对象的时候再创建该对象
4.3.2 代码实现:
class Singleton3{
//成员变量
private static Singleton3 instance;
//1.构造器私有化
private Singleton3(){}
//2.提供一个静态的getInstance()方法
//当使用该方法时,才去创建实例,既懒汉式
public static Singleton3 getInstance(){
if (instance == null){
instance = new Singleton3();
}
return instance;
}
}
4.3.3 优缺点:
- 起到了懒加载的效果(在使用时才创建),但是只能在单线程下使用
- 如果在多线程下,一个线程进入了if中判断,还未来得及往下执行,另一个线程也通过了这个if判断语句,这时便会产生多个实例,所以在多线程环境下不可以使用这种方式
- 结论:在实际开发中,不要使用这种方式
4.4 懒汉式:线程安全,同步方法
- 步骤如下:
- 和上面一样,就是在静态方法中加入了 synchronized关键字