单例模式之懒汉与饿汉

饿汉式单例模式

饿汉式是立即加载的方式,无论是否会用到这个对象,都会加载。
如果在构造方法里写了性能消耗较大,占时较久的代码,比如建立与数据库的连接,那么就会在启动的时候感觉稍微有些卡顿。

懒汉式单例模式

懒汉式,是延迟加载的方式,只有使用的时候才会加载。 并且有线程安全的考量。
使用懒汉式,在启动的时候,会感觉到比饿汉式略快,因为并没有做对象的实例化。 但是在第一次调用的时候,会进行实例化操作,感觉上就略慢。

看业务需求,如果业务上允许有比较充分的启动和初始化时间,就使用饿汉式,否则就使用懒汉式

面试几问

什么是单例模式?
回答的时候,要答到三元素

  1. 构造方法私有化
  2. 静态属性指向实例
  3. public static的 getInstance方法,返回第二步的静态属性

饿汉式代码实现

     * 饿汉式:加载类的时候,就创建了对象
     */
    public class Ehanshi {
        // 创建对象
        private static Ehanshi ehanshi = new Ehanshi();
    
        // 无参构造
        private Ehanshi() {
        }
    
        public Ehanshi getInstance() {
            return ehanshi;
        }
    
    
    }

懒汉式代码实现

    
        /**
        *   需要用的时候,才会创建对象
         *  懒汉式的多里会遇到线程安全问题
         *
         *   有可能会获取到多个实例
         */
    
        private static LhanShi lhanShi;
    
        private LhanShi() {
        }
    

        public    static LhanShi getInstance() {
            if (lhanShi == null) {
                try {
                    // 线程休眠
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                };
                lhanShi = new LhanShi();
    
            }
            return lhanShi;
    
        }
        public static void main(String[] args) {
            // 开辟10条线程
            for (int i= 0;i<10;i++){
           new Thread(new Runnable() {
               @Override
               public void run() {
                   LhanShi instance = LhanShi.getInstance();
                   System.out.println(instance.hashCode());
    
    
               }
           }).start();
            }
    
        }
    }

解决懒汉式线程同步问题

     * 需要用的时候,才会创建对象
     */
    public class LhanShi {
    
        /**
         *  懒汉式的多里会遇到线程安全问题
         *
         *   有可能会获取到多个实例
         */
    
        private static LhanShi lhanShi;
    
        private LhanShi() {
        }
    
        /**
         * synchronized:方法使用synchronized修饰,此方法同一时间只允许一条线程访问
         * @return
         */
        public  synchronized  static LhanShi getInstance() {
            if (lhanShi == null) {
                try {
                    // 线程休眠
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                };
                lhanShi = new LhanShi();
    
            }
            return lhanShi;
    
        }
        public static void main(String[] args) {
    
            // 开辟10条线程
            for (int i= 0;i<10;i++){
           new Thread(new Runnable() {
               @Override
               public void run() {
                   LhanShi instance = LhanShi.getInstance();
                   System.out.println(instance.hashCode());
    
    
               }
           }).start();
            }
    
        }
    }

你可能感兴趣的:(java)