**模式介绍:**单例设计模式就是整个软件系统中,某个类只能存在一个对象实例,并且该类只提供一个获取其对象实例的方法。
应用场景:
1.频繁实例化且频繁销毁的场景
2.和磁盘交互读写(如,操作数据库,读写文件等)
3.创建对象耗时且耗资源但又经常使用
4.工具类对象
**模式举例:**
1.Hibernate中的sessionFactory,他充当数据存储源的代理,并负责创建Session对象。一般情况下,一个项目中只需一个sessionFactory.
2.spring框架中的bean
3.java中的Runtime类
以下是推荐的几种单例设计模式:
0.引用单例模式的主类
/**
* @author Administrator
* 单例模式调用类
*/
public class SimpleMain {
public static void main(String[] args) {
System.out.println(HungarySimple.getInstance()); //饿汉式【静态常量】
System.out.println(HungarySimple2.getInstance()); //饿汉式【静态代码块】
System.out.println(DoubleCheckSimple.getInstance()); //双重检查
System.out.println(InSimple.getInstance()); //静态内部类
System.out.println(EnumSimple.INSTANCE); //枚举
EnumSimple.INSTANCE.hello();
}
}
1.饿汉式【静态常量】
/**
- 饿汉式(静态常量)
- @author Administrator
*/
public class HungarySimple {
private static final HungarySimple hSimple = new HungarySimple();
private HungarySimple() {}
public static HungarySimple getInstance() {
return hSimple;
}
}
**优点:**类装载期间完成实例化,避免了线程同步的难题【RunTime类就是这种方式】
**缺点:**在类装载期间就完成了实例化,在实例化后到使用前(或者实例化后一直未使用)这段时间会造成资源浪费。
2.饿汉式【静态代码块】
/**
* 饿汉式(静态代码块)
* @author Administrator
*
*/
public class HungarySimple2 {
private static HungarySimple2 hSimple2;
private HungarySimple2() {}
static{
hSimple2 = new HungarySimple2();
}
public static HungarySimple2 getInstance() {
return hSimple2;
}
}
3.双重检查
``/**
* 双重检查
* @author Administrator
*
*/
public class DoubleCheckSimple{
private static volatile DoubleCheckSimple simple;
private DoubleCheckSimple() {}
public static DoubleCheckSimple getInstance() {
if (simple == null) {
synchronized (SimpleMain.class) {
if (simple == null) {
simple = new DoubleCheckSimple();
}
}
}
return simple;
}
}
**优点:**多线程中经常使用,双重if判断保证了线程安全,且实例唯一,延迟加载,节省资源
4.静态内部类
/**
* @author Administrator
* 静态内部类
*/
public class InSimple {
private InSimple() {}
private static class InnerSimpleClass{
private static volatile InSimple inSimple = new InSimple();
}
public static InSimple getInstance() {
return InnerSimpleClass.inSimple;
}
}
**优点:**采用类加载机制初始化,有且仅有一个实例。静态内部类在“首次主动调用”时【即调用getInstance方法时】初始化,保证了懒加载。
5.枚举
public enum EnumSimple {
//属性
INSTANCE;
public void hello() {
System.out.println("hello world !");
}
}
优点:有效避免了多线程同步问题,还能防止反序列化重新创建新的对象
单例模式的注意细节:
当想实例化一个单例类的对象时,要使用相应的获取对象的方法,而不是使用new.