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);
        }
    
    }
    
    
  • 相关阅读:
    关于js计算非等宽字体宽度的方法
    [NodeJs系列]聊一聊BOM
    Vue.js路由管理器 Vue Router
    vue 实践技巧合集
    微任务、宏任务与Event-Loop
    事件循环(EventLoop)的学习总结
    Cookie、Session和LocalStorage
    MySQL 树形结构 根据指定节点 获取其所在全路径节点序列
    MySQL 树形结构 根据指定节点 获取其所有父节点序列
    MySQL 创建函数报错 This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators
  • 原文地址:https://www.cnblogs.com/kiki-study/p/13656104.html
Copyright © 2011-2022 走看看