关于饿汉式单例首次初始化失败后,可以再次尝试?

本文深入分析了一段使用饿汉式单例模式的Java代码,在初始化过程中遇到空指针异常的情况,并讨论了如何优雅地处理此类异常,确保程序的稳定性和健壮性。
部署运行你感兴趣的模型镜像

思考一个问题,以下代码是一个简单的饿汉式单例代码,显然在第一次初始化的时候会发生错误,导致单例的实例化失败,那么失败后可否继续尝试实例化呢?还是说下次使用时直接返回错误的对象或异常呢?

 

环境HotSpotJVM 1.6

 

/**

*

* @author lidongbo

* @date 2012-7-11

*/

public class Foo {

 

    private static final Foo foo = new Foo();

   

    private static int count = 0;

   

    private Foo(){

       init();

    }

   

    private void init(){

       //do sth.

       if(count == 0){

           //制造一个空指针

           System.out.println(foo.hashCode());

       }else{

           System.out.println("实例化成功!");

       }

       count++;

    }

   

    public static final Foo getInstance(){

       return foo;

    }

   

}

 

 

/**

 *

 * @author lidongbo

 * @date 2012-7-11

 */

public class Test {

 

    public static void main(String[] args) {

 

       try {

           System.out.println(Foo.getInstance());

       } catch (Throwable e) {

           e.printStackTrace();

       }

       System.out.println("-------------1-----------------");

       try {

           System.out.println(Foo.getInstance());

       } catch (Throwable e) {

           e.printStackTrace();

       }

       System.out.println("-------------2-----------------");

    }

 

}

 

 

答案揭晓:

再第二此实例的时候,JVM直接异常给我们了.

 

java.lang.ExceptionInInitializerError

    at Test.main(Test.java:13)

Caused by: java.lang.NullPointerException

    at Foo.init(Foo.java:19)

    at Foo.<init>(Foo.java:12)

    at Foo.<clinit>(Foo.java:9)

    ... 1 more

java.lang.NoClassDefFoundError: Could not initialize class Foo

    at Test.main(Test.java:19)

-------------1-----------------

-------------2-----------------

您可能感兴趣的与本文相关的镜像

Dify

Dify

AI应用
Agent编排

Dify 是一款开源的大语言模型(LLM)应用开发平台,它结合了 后端即服务(Backend as a Service) 和LLMOps 的理念,让开发者能快速、高效地构建和部署生产级的生成式AI应用。 它提供了包含模型兼容支持、Prompt 编排界面、RAG 引擎、Agent 框架、工作流编排等核心技术栈,并且提供了易用的界面和API,让技术和非技术人员都能参与到AI应用的开发过程中

### 懒汉式模式实现 懒汉式模式指的是在第一次使用时才创建实。这种方式的优点在于延迟了对象的创建,直到真正需要使用时才进行初始化,从而节省了系统资源。然而,懒汉式在多线程环境下存在线程安全问题,因为多个线程可能同时进入创建实的代码块,导致创建多个实。 以下是懒汉式模式的实现示: ```cpp class Singleton { private: Singleton() {} Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; static Singleton* m_instance_ptr; public: static Singleton* getInstance() { if (m_instance_ptr == nullptr) { m_instance_ptr = new Singleton; } return m_instance_ptr; } ~Singleton() {} }; ``` 在上述代码中,`static Singleton* m_instance_ptr;`中的`static`关键字用于声明一个静态成员变量,这意味着该变量属于类本身而不是类的任何特定对象。因此,无论创建多少个`Singleton`类的实,`m_instance_ptr`都只会存在一份拷贝,确保了模式的核心原则——只有一个实存在。 ### 饿汉式模式实现 饿汉式模式则是在程序启动时就创建了实,这保证了在多线程环境中实的创建是线程安全的,因为实的创建发生在程序启动阶段,此时还没有多线程竞争的问题。但是,这种方式可能会导致资源的提前占用,即使实在整个程序运行期间从未被使用过。 以下是饿汉式模式的实现示: ```cpp class Singleton { private: Singleton() {} Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; static Singleton m_instance; public: static Singleton& getInstance() { return m_instance; } ~Singleton() {} }; ``` 在这个子中,`static Singleton m_instance;`声明了一个静态成员变量,它在程序启动时就会被初始化。通过提供一个静态成员函数`getInstance()`,外部代码可以通过这个函数获取到对象的引用。 ### 区别 懒汉式与饿汉式的最大区别在于实化的时机不同。懒汉式是在第一次调用`getInstance()`方法时才创建实,而饿汉式则是在类加载时就创建实。这意味着饿汉式在程序启动时就占用了资源,而懒汉式则是在需要时才占用资源。对于懒汉式来说,需要注意处理多线程环境下的同步问题,以防止创建多个实;而饿汉式由于在程序启动时就完成了初始化,因此天然地避免了多线程环境下的实创建问题。 此外,懒汉式可以利用延迟初始化来节省资源,但如果处理不当,会导致性能问题,尤其是在高并发环境下频繁检查实是否已创建的情况。饿汉式虽然简且线程安全,但如果实的创建过程耗时较长,会影响程序的启动时间[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值