zoukankan      html  css  js  c++  java
  • 2020年9月15日 单利设计模式(面试题)

    package com.atguigu.test17;
    
    import org.junit.Test;
    
    /*
     * 单例设计模式:
     * 
     * 单例:某个类只能有唯一的一个实例对象。
     * 
     * 如何实现单例?
     * 1、饿/恶汉式
     * 不管我们使用者是否需要这个对象,它都上来先给你创建好这个唯一的对象。
     * (1)枚举类型
     * (2)形式二
     * ①构造器私有化
     * ②用一个全局的静态的常量,来保存这个唯一的实例对象
     * (3)形式三
     * ①构造器私有化
     * ②用一个私有的静态的常量,来保存这个唯一的实例对象
     * ③提供一个静态方法,来返回这个常量对象
     * 
     * 2、懒汉式
     * 延迟创建对象。当使用者来或者这个对象,要用到对象时,我再创建。
     * (1)形式一:
     * 见下面,考虑线程安全问题和性能问题
     * (2)形式二:内部类形式
     * 
     */
    public class Test17 {
        @Test
        public void test1(){
            SingleEnum s1 = SingleEnum.INSTANCE;
            SingleEnum s2 = SingleEnum.INSTANCE;
            System.out.println(s1 == s2);
        }
        
        @Test
        public void test2(){
    //        SingleEnum.test();//此时我并没有需要用到这个对象,但是它也创建出来了
        }
        
        @Test
        public void test3(){
            SingleClass s1 = SingleClass.INSTANCE;
            SingleClass s2 = SingleClass.INSTANCE;
            System.out.println(s1==s2);
        }
        
        @Test
        public void test4(){
            Single s1 = Single.getInstance();
            Single s2 = Single.getInstance();
            System.out.println(s1 == s2);
        }
        
        @Test
        public void test5(){
            LazyClass s1 = LazyClass.getInstance();
            LazyClass s2 = LazyClass.getInstance();
            System.out.println(s2 == s1);
        }
        
        LazyClass s1;
        LazyClass s2;
        @Test
        public void test6(){
            //匿名的内部类,继承Thread类
            Thread t1 = new Thread(){
                public void run(){
                    s1 = LazyClass.getInstance();
                }
            };
            
            Thread t2 = new Thread(){
                public void run(){
                    s2 = LazyClass.getInstance();
                }
            };
            
            t1.start();
            t2.start();
            
            try {
                //这里用join的目的是,为了两个子线程都执行完,再执行主线程的System.out.println(s1);
                t1.join();
                t2.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            System.out.println(s1);
            System.out.println(s2);
            System.out.println(s1 == s2);
        }
        
    }
    enum SingleEnum{
        INSTANCE;
    //    public static void test(){
    //        //..
    //    }
    }
    class SingleClass{
        public static final SingleClass INSTANCE = new SingleClass();
        private SingleClass(){
            
        }
    }
    class Single{
        private static final Single INSTANCE = new Single();
        private Single(){
            
        }
        public static Single getInstance(){
            return INSTANCE;
        }
    }
    
    class LazyClass{
        private static LazyClass instance;
        private LazyClass(){
            
        }
        
        public static LazyClass getInstance(){
            if(instance == null){//提高效率
                synchronized(LazyClass.class){//当前类的Class对象
                    if(instance == null){//安全判断
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        instance = new LazyClass();
                    }
                }
            }
            return instance;
        }
        
        //安全没问题,但是认为不是最优的,最初的线程会有安全问题,然而也会有效率问题
    /*    public synchronized static LazyClass getInstance(){
            if(instance == null){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                instance = new LazyClass();
            }
            return instance;
        }*/
        
        //有安全问题
    /*    public static LazyClass getInstance(){
    //        return new LazyClass();//错误的
            if(instance == null){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                instance = new LazyClass();
            }
            return instance;
        }*/
    }
    
    class Lazy{
        private Lazy(){
            
        }
        
        private static class Inner{
            public static final Lazy INSTANCE = new Lazy();//在内部类中,创建外部类的唯一对象
        }
        
        public static Lazy getInstance(){
            return Inner.INSTANCE;
        }
    }
    单例:整个系统中,某个类型的对象只有一个。
    
    1、饿汉式
    
    (1)枚举式
    
    ```java
    public enum Single{
        INSTANCE
    }
    ```
    
    (2)形式二
    
    ```java
    public class Single{
        public static final Single INSTANCE = new Single();
        private Single(){
            
        }
    }
    ```
    
    (3)形式三
    
    ```java
    public class Single{
        private static final Single INSTANCE = new Single();
        private Single(){
            
        }
        public static Single getInstance(){
            return INSTANCE;
        }
    }
    ```
    
    2、懒汉式
    
    (1)内部类形式
    
    ```java
    public class Single{
        private Single(){}
        
        private static class Inner{
            static final Single INSTANCE = new Single();
        }
        
        public static Single getInstance(){
            return Inner.INSTANCE;
        }
        
    }
    ```
    
    (2)形式二
    
    ```java
    public class Single{
        private static Single instance;
        private Single(){}
        
        public static Single getInstance(){
            if(instance == null){
                synchronized(Single.class){
                    if(instance == null){
                        instance = new Single();
                    }
                }
            }
            return instance;
        }
    }
    ```
  • 相关阅读:
    sql内联、左联、右联
    如何在刷新页面时不提示 "重试或取消”对话框
    js判断一个元素是否存在的方法
    springboot--email
    AdvancedInstaller
    WebService
    WCF
    WebAPI
    关于Html class id 命名规范
    Jquery Ajax 复杂json对象提交到WebService
  • 原文地址:https://www.cnblogs.com/douyunpeng/p/13673295.html
Copyright © 2011-2022 走看看