最近看了《大话设计模式》这本书,想在博客中记下以加深自己的印象。
单例模式概述
顾名思义,单例指的是:操作的类只能生成一个实例。
应用场景:网站的计数器,日志文件应用,数据库线程池等。
而在单例模式中,又分为饿汉单例模式和懒汉单例模式。以下便通过代码展示出其区别。
饿汉单例模式
我们在通过Java获取一个对象时,一般是通过new调用类的构造函数生成,而当我们需要控制该类单例时,就需要将构造函数的访问权限设置为private以使得其他类无法通过构造方法创建实例,并给予一个类方法来获取Singleton类对象。
//代码块一
package com.singleton;
public class Singleton {
//饿汉单例模式,在调用该类的第一时间就创建了对象
private static Singleton instance = new Singleton();
private Singleton() {
}
//定义一个类方法, 需要使用到Singleton实例时调用该方法获取
public static Singleton getInstance() {
return instance;
}
}
这种静态初始化的方式是在自己被加载时就将自己实例化,所以被称之为饿汉单例类。
懒汉单例模式
其他类需要使用Singleton的类对象时,只能通过类方法getInstance()获取到Singleton对象。
//代码块二
package com.singleton;
public class Singleton {
//懒汉单例:没有在调用该类的第一时间就创建一个对象, 而是在getInstance中根据条件创建
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
//只有当实例为空的时候才进行实例的创建
if(instance == null)
instance = new Singleton();
return new Singleton();
}
}
这种要在第一次被引用时,才会将自己实例化的类,称之为懒汉单例类。
但是代码块二 在多线程的情况下,无法保证只生成一个对象,因此需要再修改为以下代码来确保多线程下只有一个对象。
//代码块三
package com.singleton;
public class Singleton {
//懒汉单例:没有在调用该类的第一时间就创建一个对象, 而是在getInstance中根据条件创建
private static Singleton instance;
private Singleton() {
}
//增加synchronized
public synchronized static Singleton getInstance() {
//只有当实例为空的时候才进行实例的创建
if(instance == null)
instance = new Singleton();
return new Singleton();
}
}
总结
由于饿汉单例模式是在类一加载的时候就生成实例,所以要提前占用系统资源;
懒汉单例模式又要面临着多线程访问的安全性问题,需要做到同步才可保证安全。
才疏学浅,如文中有错误,感谢大家指出。