【设计模式】8种方式实现单例模式

8种方式实现单例模式

1、饿汉式的两种写法

饿汉式的特点:在获取单例对象之前对象就已经创建完成了。

package com.JUC编程.volatile0;
public class SingleEh {
    //饿汉式单例模式
    //1.静态常量
   /* private static final SingleEh singleEh=new SingleEh();
    private SingleEh(){
    }
    public static SingleEh getSingleEh(){
        return singleEh;
    }*/
    //2.静态代码块
    private static final SingleEh singleEh;
    private SingleEh(){
    }
    static {
        singleEh=new SingleEh();
    }
    public static SingleEh getSingleEh(){
        return singleEh;
    }
}
class test{
    public static void main(String[] args) {
        SingleEh singleEh = SingleEh.getSingleEh();
        SingleEh singleEh1 = SingleEh.getSingleEh();
        System.out.println(singleEh1 == singleEh);//true
    }
}
2、懒汉单例的四种写法

懒汉单例的特点:在真正需要单例的时候才创建出该对象。

package com.JUC编程.volatile0;
public class SingleLh {
    //懒汉式单例模式
    //1.线程不安全
    private SingleLh(){
    }
    private static SingleLh singleLh;//定义的时候不初始化
    public static SingleLh getSingleLh(){
        //当有两个线程同时进入到这个方法中时,就会发生线程安全问题
        if (singleLh==null) {
            return new SingleLh();
        }
        return singleLh;
    }
}
package com.JUC编程.volatile0;
public class SingleLh {
    //2.使用synchronized修饰方法,但是性能太低
    private SingleLh(){
    }
    private static SingleLh singleLh;
    public synchronized static SingleLh getSingleLh(){
        if (singleLh==null) {
            return new SingleLh();
        }
        return singleLh;
    }
}
package com.JUC编程.volatile0;
public class SingleLh {
    //3.可以缩小synchronized的使用范围,但是我们发现却保证不了线程安全
    private SingleLh(){
    }
    private static SingleLh singleLh;
    public synchronized static SingleLh getSingleLh(){
        if (singleLh==null) {
            synchronized (SingleLh.class) {
                return new SingleLh();
            }
        }
        return singleLh;
    }
}

volatile双重检查机制(推荐方式)

package com.JUC编程.volatile0;
public class SingleLh {
    //4.volatile双重检查模式(推荐)
    private SingleLh(){
    }
    //volatile在此处主要的作用是保证可见性和禁止指令重排序
    private volatile static SingleLh singleLh;
    public  static SingleLh getSingleLh(){
        /*双重检查既保证了效率又保证了线程安全*/
        if (singleLh==null) {
            synchronized (SingleLh.class) {
                if(singleLh==null) {
                //因为new SingleLh()并不是一个原子操作,可能会发生指令重排。
                    return new SingleLh();
                }
            }
        }
        return singleLh;
    }
}
3、静态内部类单例方式

静态内部类是在被调用时才会被加载,这种方案实现了懒汉单例的一种思想,需要用到的时候才会去创建单例,加上JVM的特性,这种方式又实现了线程安全的创建单例对象。

package com.JUC编程.volatile0;
public class SingleStatic {
    /*步骤:
    * 1.提供一个静态内部类来,里面提供一个常量用来存储单例对象
    * 2.提供一个静态方法返回静态内部类中的单例对象
    * */
    private SingleStatic(){
    }
    private static class InnerClass{
        private static final SingleStatic single=new SingleStatic();
    }
    public static SingleStatic getSingleStatic(){
        return InnerClass.single;
    }
}
4、枚举实现单例
package com.JUC编程.volatile0;
/*
* 枚举实际上是一种多例的模式,如果我们直接定义了一个实例就相当于是单例了
* */
public enum  SingleEnum {
    //但是枚举的主要作用是用于信息的标志和分类,不足以应付特殊的应用场景,单例中用的较少
    SINGLE_ENUM;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值