您的位置 首页 java

Java 单例模式简单吗?

我们来实现一个日常非常熟悉的单例设计模式。看起来似乎很简单,那么下面这个样例符合基本 需求吗?

是不是总感觉缺了点什么?原来, Java 会自动为没有明确声明 构造函数 的类,定义一个 public 的无参数的构造函数,所以上面的例子并不能保证额外的对象不被创建出来,别人完全可以直 接“new Singleton()”,那我们应该怎么处理呢?

不错,可以为单例定义一个 private 的构造函数,这样还有什么改进的余地吗?

当然了,标准类库中很多地方使用懒加载(lazy-load),改善初始内存开销,单例同样适用,下面是修正后的改进版本。

这个实现在单线程环境不存在问题,但是如果处于并发场景,就需要考虑 线程安全 ,最熟悉的就 莫过于“双检锁”,其要点在于:

1)这里的 volatile 能够提供可见性,以及保证 getInstance 返回的是初始化完全的对象。

2)在同步之前进行 null 检查,以尽量避免进入相对昂贵的同步块。

3)直接在 class 级别进行同步,保证线程安全的类方法调用。

在这段代码中,争论较多的是 volatile 修饰 静态变量 ,当 Singleton 类本身有多个成员变量 时,需要保证初始化过程完成后,才能被 get 到。

在现代 Java 中,内存排序模型(JMM)已经非常完善,通过 volatile 的 write 或者 read,能 保证所谓的 happen-before,也就是避免常被提到的指令重排。换句话说,构造对象的 store指令能够被保证一定在 volatile read 之前。

当然,也有一些人推荐利用内部类持有静态对象的方式实现,其理论依据是对象初始化过程中隐 含的初始化锁

所以,可以看出,即使是看似最简单的 单例模式 ,在增加各种高标准需求之后,同样需要非常多 的实现考量。

文章来源:智云一二三科技

文章标题:Java 单例模式简单吗?

文章地址:https://www.zhihuclub.com/182404.shtml

关于作者: 智云科技

热门文章

网站地图