单例对象的几种创建方式

    技术2025-03-19  36

    1、饿汉式

    public class SingletonInstance{ private static final SingletonInstance instance = new SingletonInstance(); private SingletonInstance(){ } public static SingletonInstance getInstance(){ return instance ; } }

     

    在类加载时就创建对象,可以确保单理对象的唯一性,但如果整个过程不使用,会造成资源浪费。

     

    2、懒加载

    public class SingletonInstance{ private static SingletonInstance instance = null; private SingletonInstance(){ } public static SingletonInstance getInstance(){ if(instance == null){ instance = new SingletonInstance() } return instance ; } }

     

    懒加载的方式不会造成资源浪费,但却带来了线程安全问题,在互联网的高并发情况下,可能比资源浪费还要严重。但可以进行优化,避免线程安全问题。

     

    2.1)加锁懒汉式

    对于多线程并发带来的安全问题,我们可以使用加上线程同步锁(synchronized关键字)来解决。

    public class SingletonInstance{ private static SingletonInstance instance = null; private SingletonInstance(){ } public static synchronized SingletonInstance getInstance(){ if(instance == null){ instance = new SingletonInstance() } return instance ; } }

     

    加锁synchronized后可以解决线程安全的问题,可以进一步优化如下

    2.2)双重判断锁定的懒汉式

    public class SingletonInstance{ private static volatile SingletonInstance instance = null; private SingletonInstance(){} public static SingletonInstance getInstance(){ if(instance == null){ synchronized(SingletonInstance.class){ if(instance == null){ instance = new SingletonInstance() } } } return instance; } }

     

    当instance不为空时,直接返回,不用加锁和重新创建了,可以减少加锁次数,提高性能。

    3、静态内部类(IoDH)

    饿汉式单例类不能实现延迟加载,不管用不用都始终占据内存;懒汉式单例类线程安全控制烦琐,而且性能受影响。

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

     

    静态内部类能实现延迟加载的原因:Java内部静态类在调用时才加载(懒加载)。

    通过使用IoDH,既可以实现延迟加载,又可以保证线程安全,不影响系统性能。缺点是与编程语言本身的特性相关,很多面向对象语言不支持IoDH。

    Processed: 0.010, SQL: 9