【单例模式】

/*
               面向对象的三大特性:封装性,继承性以及多态性
        单例设计模式:(封装性)
            1、构造方法私有化
            2、声明一个本类对象(私有并且静态)
            3、给外部提供一个静态方法获取对象实例(私有并且静态)
        1、饿汉模式:在第一次调用getInstance方法时,对象被创建,到程序结束后释放
        2、懒汉模式:在类被加载后,对象被创建,到程序结束后释放

        在项目中为什么要使用单例,单例有什么好处呢?
        1、在设计一些工具类的时候(通常工具类,只有功能方法,没有属性)
        2、工具类可能被频繁使用

        目的是为了节省重复创建带来的内存消耗,从而提高效率
        

     */

public class FaceObject implements Serializable {//让单例类可以被序列化

    public static void main(String[] args) {

        Singleton s = Singleton.getInstance();
        s.method();
        Singleton s2 = Singleton.getInstance();
        s2.method();
        System.out.println(s == s2);
        int i =Math.max(0,127);
        System.out.println(i);
    }


    //饿汉模式单例
    static class Singleton {
       private Singleton(){}//构造方法私有化
        private static Singleton s =new Singleton();//创建本类对象
        private static Singleton getInstance(){//提供一个获取本类对象的方法(私有并且静态)
            return s;
        }
        public void method(){
            System.out.println("饿汉单例模式运行");
        }
    }

    //懒汉模式单例
    static class Singleton2 {
        private Singleton2() {
            if(s2!=null){//防止反射调用私有构造方法
                throw new RuntimeException("此类对象为单例模式,已经被实例化了");
            }
        }
        private volatile static Singleton2 s2=null;//加上volatile关键字保证变量的一致性

        private static Singleton2 getInstance() {
            //双重判断解决多线程问题
            if (s2 == null) {//第一次判断是判断是否已经创建了对象
                synchronized (Singleton2.class) {//加锁,解决线程安全的问题
                    if (s2 == null) {//是抢到第一次cpu时间片的线程用来判断是否已经创建对象
                        s2 = new Singleton2();
                    }
                }
            }
            return s2;
        }
    }
}
/**
 * DCL 懒汉模式单例(加强版)
 * */
public class LazyMan {

    private static boolean token=false;
    
    private LazyMan(){
        //加锁防止使用反射来破坏异常
        synchronized (LazyMan.class){
            if(token){//token是防止两次反射创建对象
                throw new RuntimeException("禁止使用反射破坏单例");
            }else {
                token=true;
            }
        }
//        System.out.println(Thread.currentThread().getName()+"ok");
    }
    //加volatile防止指令重排(在 lazyMan=new LazyMan(); 可能发生,浪费内存)
    private volatile static LazyMan lazyMan;
    public static LazyMan getInstance(){
        if(lazyMan==null){
            //加锁
            synchronized (LazyMan.class){
                //二次判断
                if(lazyMan==null){
                    lazyMan=new LazyMan();//不是原子操作
                    /**
                     * 1、分配内存空间
                     * 2、执行构造方法
                     * 3、引用对象指向内存空间
                     * */
                }
            }
        }
        return lazyMan;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@一只牛码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值