手写单例模式

这篇博客深入探讨了Java中的三种单例模式实现:懒汉模式、饿汉模式和双重检查锁单例。懒汉模式在多线程环境中存在线程安全问题,可以通过同步方法解决,但会降低效率。饿汉模式在类加载时即创建实例,保证线程安全但可能导致内存浪费。双重检查锁单例则在保证线程安全的同时实现了延迟加载,提高了效率。
摘要由CSDN通过智能技术生成
package com.jan;

/***
 * 手写单例模式
 *
 *懒汉模式
 * 饿汉模式
 * 双重检查锁单例
 */
//懒汉模式
public class SingleTon {

    private static SingleTon single;

    public SingleTon() {
    }

    /***
     * 缺陷: 线程不安全,如果两个线程同时访问到了getSingleTon()方法,
     * 并且都走到了“single == null”这个判断时,此时single实例未被创建,
     * 所以两个线程都会创建一个实例
     */
    public static SingleTon getSingleTon() {
        if(single==null){
            single = new SingleTon();
        }
        return single;
    }

    /***
     * 改进:
     * 优点: 第一次调用才初始化,避免内存浪费
     * 缺点: 必须加锁 synchronized 才能保证单例,但加锁会影响效率
     * @return
     */
    public static synchronized  SingleTon getSingle1(){
        if(single==null){
            single = new SingleTon();
        }
        return single;
    }
}
//饿汉模式
/***
 * 饿汉式更为安全,在类加载的时候就已经自行创建了实例,
 * getSingle2方法里面一直引用的就是这个实例,而且永远不会释放,一直存在内存中,知道程序结束
 */
 class SingleTon2 {

    private static SingleTon2 single2 = new SingleTon2();

    public SingleTon2() {
    }

    public static synchronized  SingleTon2 getSingle2(){
        return single2;
    }
}


//双重检查

/***
 * 其中用了两个if 判断,第一个if 先判断singleton是否为null,
 * 如果不为null,说明singleton 已经被初始化了,直接返回singleton
 * 避免了多个线程同时获取synchronized 锁;
 * 如果singleton 为null ,说明singleton 还没有被初始化,
 * 这样才会去执行synchronized 修饰的代码块内容,只在其初始化的时候调用一次。
 * 这样的设计既能保证只产生一个实例,并且只在初始化的时候加同步锁,也实现了延迟加载。

 */
 class SingleTon3 {
    // volatile可以实现多线程的可见性 有序性 但是不保证一致性
    private static volatile  SingleTon3 single3;

    public SingleTon3() {
    }

    public static  SingleTon3 getSingle3(){
        // 最外层if 过滤掉不为null 的线程 提高效率
        if(single3==null){
            synchronized (SingleTon3.class){
                if(single3==null){
                    single3 = new SingleTon3();
                }
            }
        }
        return single3;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值