单例模式

简介

单例模式在是指在程序运行过程中只存在一个该类的实例,这对于复杂的项目来说减轻了项目运行时的负担。因此在许多框架中有着重要的应用,比如Spring.
对于严格限制的单例模式,单例类应该具有以下特点:
1.私有化构造器
2.在类的内部将实例创建
3.提供静态公共的获取实例的方法
单例模式分为饿汉式(一种)和懒汉式(三种),下面将依次介绍:

饿汉式

饿汉式,即在类加载时就将其初始化 或者置于静态块中

/**
 * 饿汉式单例1
 */
public class SingletonStudent {
    // 在类加载时就将其初始化 或者置于静态块中
    private static SingletonStudent singleStudent =new SingletonStudent();

    // 私有化构造器
    private SingletonStudent(){};

    public static SingletonStudent getInstance()
    {
        return SingletonStudent.singleStudent;
    }
}

优点:实现了单例模式,不用考虑线程安全的问题
缺点:增加了程序启动时的负担。

懒汉式第一种

懒汉式,即在程序调用时再将对应变量初始化

/**
 * 懒汉式单例第一种
 */
public class LazySingletonStudent1 {

    private static LazySingletonStudent1 student1 =null;

    private LazySingletonStudent1(){};

    /**
     * 优点:锁住这个方法,使得同时只有一个线程进入了方法,并且只有在调用到时才会被初始化,
     * 缺点:虽然保证了单例,但是在单例被实例化后,仍然同时只有一个线程进入了方法,对性能影响严重
     */
    public static synchronized LazySingletonStudent1 getInstance()
    {
        if(student1==null){
            student1=new LazySingletonStudent1();
        }
        return student1;
    }
}
懒汉式第二种
/**
 * 懒汉式单例第二种
 */
public class LazySingletonStudent2 {

    private static LazySingletonStudent2 student2 =null;

    private LazySingletonStudent2(){};

    /**
     * 优点:满足懒加载需求,采用同步块的形式,使得加载完成的后续使用中对性能无影响
     * 缺点:初次使用为多线程访问同时加载时有影响。
     */
    public static LazySingletonStudent2 getInstance()
    {
        if(student2==null){
            synchronized (student2) {
                if(student2==null){
                    student2=new LazySingletonStudent2();
                }
            }
        }
        return student2;
    }
}
懒汉式第三种
/**
 * 懒汉式单例第三种
 */
public class LazySingletonStudent3 {

    private LazySingletonStudent3(){};

    /**
     * 优点:利用内部类的延迟加载机制,
     * 在内部类加载时对自身变量进行初始化,完美解决了前两种方法的缺陷
     */
    private static class InnerSingleStu{
        private static final LazySingletonStudent3 innerStu = new LazySingletonStudent3();
    }

    public static LazySingletonStudent3 getInstance()
    {
        return InnerSingleStu.innerStu;
    }
}

一笔题外话:SpringContainer容器中的bean是单例的,由Spring创建,在调用时传递引用。而这些单例对象在多线程下能保持线程安全的原因是,这些对象的属性都是无状态的,(没有实参和集合,只有形参,而且,形参也是无状态的),具体请参考《java并发编程实战》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值