zoukankan      html  css  js  c++  java
  • GOF23之单例模式(手撕代码)

    1、单例模式
    饿汉式

    package com.itheima.kiki.single;
    
    /**
     * 饿汉式单例
     * 构造器私有,一旦私有构造器,别人就无法new对象了,保证内存中只有一个对象
     *
     */
    public class HungaryDemo {
        //构造器私有
        private HungaryDemo(){
    
        }
        //创建对象
        private final static HungaryDemo HUNGARY_DEMO = new HungaryDemo();
    
        //返回对象实例
        public static HungaryDemo getInstance(){
            return HUNGARY_DEMO;
        }
    
    }
    

    懒汉式

    package com.itheima.kiki.single;
    
    /**
     * 懒汉式单例
     */
    public class LazyDemo {
        private LazyDemo(){
            System.out.println(Thread.currentThread().getName()+ "ok");
        }
    
        private volatile static LazyDemo lazyDemo;
    
        public static LazyDemo getInstance(){
            //双重检测锁模式的懒汉式单例(DCL懒汉式)
            if(lazyDemo == null){
                synchronized (LazyDemo.class){
                    if (lazyDemo == null){
                        lazyDemo = new LazyDemo();//不是原子性操作
                        /**
                         * 1、分配内存空间
                         * 2、执行构造方法,初始化对象
                         * 3、把这个对象指向这个空间
                         *  123
                         *  132 A线程
                         *      B线程 此时lazyDemo还没有完成构造
                         *
                         */
                    }
                }
            }
            return lazyDemo;
        }
    
        //多线程并发
        public static void main(String[] args) {
            for (int i = 1; i <= 10; i++) {
                new Thread(()->{
                    lazyDemo.getInstance();
                }).start();
            }
        }
    
    }
    
    

    破坏单例

    package com.itheima.kiki.single;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    
    
    /**
     * 懒汉式单例
     */
    public class LazyDemo2 {
    
        private static boolean kiki = false;
    
        private LazyDemo2(){
    
            synchronized (LazyDemo2.class){
                if (kiki==false){
                    kiki=true;
                }else {
                    throw new RuntimeException("不要试图使用反射破坏异常");
                }
    
            }
            System.out.println(Thread.currentThread().getName()+ "ok");
        }
    
        private volatile static LazyDemo2 lazyDemo;
    
        public static LazyDemo2 getInstance(){
            //双重检测锁模式的懒汉式单例(DCL懒汉式)
            if(lazyDemo == null){
                synchronized (LazyDemo2.class){
                    if (lazyDemo == null){
                        lazyDemo = new LazyDemo2();//不是原子性操作
                    }
                }
            }
            return lazyDemo;
        }
    
        //反射
        public static void main(String[] args) throws Exception{
            //LazyDemo2 instance = LazyDemo2.getInstance();
            Field kiki = LazyDemo2.class.getDeclaredField("kiki");
            kiki.setAccessible(true);
            Constructor<LazyDemo2> declaredConstructor = LazyDemo2.class.getDeclaredConstructor(null);
            declaredConstructor.setAccessible(true);//设置无视私有构造器
    
            LazyDemo2 instance = declaredConstructor.newInstance();
    
            kiki.set(instance,false);
    
            LazyDemo2 instance2 = declaredConstructor.newInstance();
    
            System.out.println(instance);
            System.out.println(instance2);
        }
    
    }
    
    
  • 相关阅读:
    codevs2606 约数和问题
    UOJ150 运输计划
    codevs1279 Guard 的无聊
    codevs1997 守卫者的挑战
    codevs1291 火车线路
    codevs1217 借教室
    codevs1281 Xn数列
    codevs1218 疫情控制
    codevs1199 开车旅行
    BZOJ1941 [Sdoi2010]Hide and Seek
  • 原文地址:https://www.cnblogs.com/kiki-study/p/13656104.html
Copyright © 2011-2022 走看看