java单例模式

之前只知道单例模式有两种:懒汉式和饿汉式,后来因为看到一句话,如果你将构造函数私有化,别人使用反射,这个时候怎么办,所以就知道了第三种方式枚举模式。然后今天又看到了静态内部类式和双重检测锁,今天就总结一下。

一、单例模式

(1)核心:保证只有一个实例,并提供一个访问全局的访问点。

(2)使用场景:

         Windows的任务管理器

   .Windows的回收站

         项目中读取配置文件,没有必要每次都进行读取。

         网站计数器

        日志管理   

        数据库连接池,等等

(3)优点

      使用单例只生成一个对象,减少系统的开销,对于一个对象产生需要比较多的资源,如配置、产生依赖对象时,我们可以使用单例对象

      单例模式可以设置全局的访问点,共享资源的访问。

2.单例设计模式的实现方式

 (1)饿汉式:线程安全,调用效率高,但是不延迟加载

           a) 首先私有构造函数

           b) 使用私有得静态变量创建一个方法

           c) 提供一个静态的方法访问次对象

          它是一个线程安全的的模式,对象不是自己来创建,而是有一个对象等待使用,不需要同步,效率高。

         浪费资源,没有延迟加载。

实现方式:

package kw.test.sjms;
/*
 * 单例模式
 *     饿汉式单例模式
 * 
 */
public class DemoEH {
    private static DemoEH instance = new DemoEH();
    private DemoEH() {}
    public  static DemoEH getInstace()
    {
        return instance;
    }
}

 (2)懒汉式:线程安全,调用效率不高,但是,可以延迟加载

    ··· 使用的时候才去加载,但是需要使用synchronized

·   ··· 资源利用率高,但是效率不是很高。

     ···缺点:每次都需要同步,浪费资源。

实现方式:

package kw.test.sjms;
/*
 * 懒汉式单例模式
 */
public class DemoLH {
    private static DemoLH instance ;
    private DemoLH(){}
    public synchronized static DemoLH  getinstance(){
        if(instance == null)
        {
            instance = new DemoLH();
        }
        return instance;
    }
}

(3) 双重检测锁式:由于JVM层底内部模型原因,偶尔会出现问题,不建议使用。

         ·解决了懒汉式的每次都需要锁判断的资源浪费。

   ·将锁放到if判断的内部,提高了效率,不需要每次都进行同步。

package kw.test.sjms;

/*
 * 双重锁的单例模式
 */
public class DemoSCS {
    private DemoSCS(){}
    private static DemoSCS instance = null ;
    
    public static DemoSCS getInstance() {
        if(instance == null)
        {
            DemoSCS demoSCS;
            synchronized (DemoSCS.class) {
                if(instance == null)
                {
                    instance = new DemoSCS();
                }            
            }
        }
        return instance;
    }
}

(4)静态内部类式:线程安全,调用效率高,但是可以延迟加载

         ·线程安全、效率高于懒汉式,并且有懒加载。

package kw.test.sjms;

/*
 * 静态内部类
 */
public class DemoJTNB {
    private static class createInstance {
        private static final DemoJTNB instance = new DemoJTNB();
    }
    private DemoJTNB()
    {
    }
    public  static DemoJTNB getInstance() {
        return createInstance.instance;
    }
}

(5) 枚举单例:线程安全,调用效率高,不能延迟加载,可以防止反射创建。

         ·枚举是天然的单例。但是没有延迟加载的功能。

package kw.test.sjms;

public enum DemoMJ {
    instace;
    public void getInstance() {
    }
}

最好的模式:线程安全、调用效率高、要有懒加载。最完美的实现方式。

原文地址:https://www.cnblogs.com/kw28188151/p/8545184.html