zoukankan      html  css  js  c++  java
  • 设计模式(三)Singleton Pattern单例设计模式

    1.饿汉式

    public class SingletonDemo {
        private static SingletonDemo s=new SingletonDemo();
        private SingletonDemo() {}
        public static SingletonDemo getInstance() {
                return s;
        }
    }
    public class Test {
        public static void main(String[] args) {
            SingletonDemo s=SingletonDemo.getInstance();
        }
    }

    步骤:    1.new出静态对象

        2.构造方法私有化

        3.写一个方法返回静态对象

    说明:   1.由于加载类时天然的是线程安全

        2.方法没有同步,调用效率高

        3.立即加载,没有延时加载的优势

    2.懒汉式(延时加载)

    public class SingletonDemo {
        private static SingletonDemo s;
        private SingletonDemo() {}
        public static synchronized SingletonDemo getInstance() {
                if(s==null) s=new SingletonDemo();
                return s;
        }
    }
    public class Test {
        public static void main(String[] args) {
            SingletonDemo s=SingletonDemo.getInstance();
        }
    }

    优势:   1.修改点同步,在线程高并发时,能够保证安全性

        2.延时new出类,能够做到用的时候去new它

    3.双重检测锁实现

    由于java编译器优化的原因和JVM底层内部模型的原因,偶尔会出一点问题,不建议使用

    这个模式将同步内容下方到if内部,提高了执行效率,不必每次获取对象时都进行同步,至于一次才同步

    public class SingletonDemo {
        private static SingletonDemo instance;
        private SingletonDemo() {}
        public static SingletonDemo getInstance() {
            if(instance==null) {
                SiSingletonDemo sc;
                synchronized (SingletonDemo.class) {
                    sc=instance;
                }
                if(sc==null) {
                    synchronized (SingletonDemo.class) {
                        if(sc==null) {
                            sc=new SingletonDemo();
                        }
                    }
                    instance=sc;
                }
            }
            return instance;
        }
    }

    4.静态内部类(懒加载)

    public class SingletonDemo {
        private static class SingletonClassInstance{
            private static final SingletonDemo instance=new SingletonDemo();
        }
        private SingletonDemo() {}
        public static SingletonDemo getInstance() {
            return SingletonDemo.getInstance();
        }
    }

     5.枚举单例模式

    public enum SingletonDemo {
        INSTANCE;    //枚举本来就是单例对象
        //避免了反序列和反射的调用
        //缺点,没有延时调用
        public void singletonOperation() {
            
        }
    }

     6.统一建模语言UML(unified modeling language)

    可以拖动类做uml图

    利用反射破解单例设计模式(不包含枚举单例,因为枚举型单例是利用JVM底层实现的单例设计模式)

    public class TestSingleObject {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            SingleObject s1=SingleObject.getInstance();
            SingleObject s2=SingleObject.getInstance();
            
            Class<SingleObject> clazz=(Class<SingleObject>) Class.forName("com.littlepage.singletonPattern.SingleObject");
            Constructor<SingleObject> c=clazz.getDeclaredConstructor(null);
            c.setAccessible(true);//跳过检测
            SingleObject s3=c.newInstance();
            SingleObject s4=c.newInstance();
            System.out.println(s1);
            System.out.println(s2);
            System.out.println(s3);
            System.out.println(s4);
        }
    }

    解决方法,在空参构造中加入

    if(SingletonObject!=null){

    throw new runtimeExpection();

    }

    进行调用时抛出异常就行

    //举例
    public class SingleObject {
        public static class SingleObjectInstance{
            public static final SingleObject instance=new SingleObject();
        }
        private SingleObject(){
            if(SingleObjectInstance.instance!=null){
                try {
                    throw new Exception("运行时异常");
                    
                } catch (Exception e) {
                    e.printStackTrace();
                    System.exit(0);
                }
            }
        }
        public static SingleObject getInstance(){
            return SingleObjectInstance.instance;
        }
    }

     利用序列化反序列化进行破解

    public class TestSingleObject {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            SingleObject s1=SingleObject.getInstance();
            System.out.println(s1);
            FileOutputStream fops=new FileOutputStream("d:/a.txt");
            ObjectOutputStream oops=new ObjectOutputStream(fops);
            oops.writeObject(s1);
            oops.close();
            
            ObjectInputStream ois =new ObjectInputStream(new FileInputStream("d:/a.txt"));
            SingleObject s2=(SingleObject) ois.readObject();
            System.out.println(s2);
            ois.close();
            
        }
    }

    解决办法:

    private Object resdResolve() throws ObjectStreamException{
            return SingleObjectInstance.instance;
        }

    添加该代码,可以使读取Object时直接返回已经存在的实例

  • 相关阅读:
    父子传值
    第三次作业
    第二次作业
    最后一次作业--总结报告
    Vue项目axios请求设置responseType无效
    滚动条样式修改
    超出部分显示省略号,鼠标悬浮显示详细文本,el-tooltip
    大屏rem
    js比较时间大小
    kindeditor编辑器上传图片跨域
  • 原文地址:https://www.cnblogs.com/littlepage/p/9977450.html
Copyright © 2011-2022 走看看