Java单例模式

单例模式

饿汉式

  • /**
     * @Author 嘉宾
     * @Date 2021/9/7 9:01
     * @Description: 饿汉式单例
     */
    public class Hungry {
        
        //可能会浪费空间
        private byte[] data1 = new byte[1024*1024];
        private byte[] data2 = new byte[1024*1024];
        private byte[] data3 = new byte[1024*1024];
        private byte[] data4 = new byte[1024*1024];
    ​
        public Hungry() {
        }
    ​
        private final static Hungry HUNGRY = new Hungry();
    ​
        public static Hungry getInstance(){
            return HUNGRY;
        }
    }

懒汉式

  • /**
     * @Author 嘉宾
     * @Date 2021/9/7 9:04
     * @Description: 懒汉式
     */
    public class LazyMan {
    ​
        private static boolean jiabin = false;
    ​
        private LazyMan() {
            synchronized (LazyMan.class){
                if(jiabin==false){
                    jiabin = true;
                }else{
                    throw new RuntimeException("不要视图使用反射破坏异常");
                }
            }
            System.out.println(Thread.currentThread().getName()+"ok!");
        }
    ​
        private volatile static LazyMan lazyMan;
    ​
        //双重监测锁模式的懒汉式单例:DCL懒汉式
        public static LazyMan getInstance(){
            //枷锁
            if(lazyMan==null){
                synchronized (LazyMan.class){
                    if(lazyMan==null){
                        lazyMan = new LazyMan();    //不是一个原子性操作
                      
                    }
                }
            }
            return lazyMan; //此时这个lazyMan还没有完成构造
        }
    ​
        //反射
        public static void main(String[] args) throws Exception {
            //LazyMan instance = LazyMan.getInstance();
    ​
            Field jiabin = LazyMan.class.getDeclaredField("jiabin");
            jiabin.setAccessible(true);
    ​
            Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
            declaredConstructor.setAccessible(true);
            LazyMan instance = declaredConstructor.newInstance();
    ​
            jiabin.set(instance,false);
    ​
            LazyMan instance2 = declaredConstructor.newInstance();
    ​
            System.out.println(instance);
            System.out.println(instance2);
        }
    ​
        /**
         * 1.分配内存空间
         * 2.执行构造方法
         * 3.把这个对象指向这个空间
         */
        
        // 缺点:单线程下确实ok,
    //    public static void main(String[] args) {
    //        for(int i = 0;i< 10;i++){
    //            new Thread(()->{
    //                LazyMan.getInstance();
    //            }).start();
    //        }
    //    }
    }

静态内部类

/**
 * @Author 嘉宾
 * @Date 2021/9/7 9:14
 * @Description: 静态内部类
 */
public class Holder {
​
    private Holder() {
    }
​
    public static Holder getInstance(){
        return InnerClass.HOLDER;
    }
​
    public static class InnerClass{
        private static final Holder HOLDER = new Holder();
    }
}

单例不安全,因为有反射

/**
 * @Author 嘉宾
 * @Date 2021/9/7 9:24
 * @Description: enum是什么?本身也是一个class类
 */
public enum EnumSingle {
​
    INSTANCE;
​
    public EnumSingle getInstance(){
        return INSTANCE;
    }
​
}
​
class Test{
    public static void main(String[] args) throws Exception {
        EnumSingle instance1 = EnumSingle.INSTANCE;
        Constructor<EnumSingle> declaredConstructor = EnumSingle.class.getDeclaredConstructor(String.class,int.class);
        declaredConstructor.setAccessible(true);
        EnumSingle instance2 = declaredConstructor.newInstance();
​
        System.out.println(instance1);
        System.out.println(instance2);
    }
}

枚举类型的最终反编译

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值