面试处处都是坑啊?让实现线程安全的单例,又不让用synchronized

本文介绍了如何在面试中应对不使用`synchronized`实现线程安全单例模式的问题,探讨了静态内部类、枚举、CAS和ThreadLocal等实现方式,以及如何防止反射和序列化破坏单例模式。面试官通过这种方式考察候选人的并发知识、设计模式理解和类加载机制等多方面技能。
摘要由CSDN通过智能技术生成

单例模式,是Java中比较常见的一个设计模式,也是我在面试时经常会问到的一个问题。

 

经过我的初步统计,基本上有60%左右的人可以说出2-4种单例的实现方式,有40%左右的人可以说出5-6种单例的实现方式,只有20%左右的人能够说出7种单例的实现。

 

而只有不到1%的人能够说出7种以上的单例实现。

 

其实,作为面试官,我大多数情况下之所以问单例模式,是因为这个题目可以问到很多知识点。

 

比如线程安全、类加载机制、synchronized的原理、volatile的原理、指令重排与内存屏障、枚举的实现、反射与单例模式、序列化如何破坏单例、CAS、CAS的ABA问题、Threadlocal等知识。

 

一般情况下,只需要从单例开始问起,大概就可以完成一场面试的整个流程,把我想问的东西都问完,可以比较全面的了解一个面试者的水平。

 

以下,是一次面试现场的还原,从单例模式开始:

 

Q:你知道怎么不使用synchronized和lock实现一个线程安全的单例吗?

A:我知道,可以使用"静态内部类"实现。

 

静态内部类实现单例模式:

 

 

Q:除了静态内部类还会其他的方式吗?

A:还有就是两种饿汉模式。

 

饿汉实现单例模式:

 

 

 

饿汉变种实现单例模式:

 

 

Q:那你上面提到的几种都是线程安全的吗?

A:是线程安全的

Q:那是如何做到线程安全的呢?

A:应该是因为我使用了static,然后类加载的时候就线程安全了吧?

Q:其实你说的并不完全对,因为以上几种虽然没有直接使用synchronized,但是也是间接用到了。

(这里面根据回答情况会朝两个不同的方向展开:1、类加载机制、模块化等;2、继续深入问单例模式)

 

类加载过程的线程安全性保证

以上的静态内部类、饿汉等模式均是通过定义静态的成员变量,以保证单例对象可以在类初始化的过程中被实例化。

 

这其实是利用了ClassLoader的线程安全机制。ClassLoader的loadClass方法在加载类的时候使用了synchronized关键字。

所以, 除非被重写,这个方法默认在整个装载过程中都是线程安全的。所以在类加载过程中对象的创建也是线程安全的。

 

Q:那还回到刚开始的问题,你知道怎么不使用synchronized和lock实现一个线程安全的单例吗?

(并不是故意穷追不舍,而是希望能可以引发面试者的更多思考)

A:额、、、那枚举吧,枚举也可以实现单例。

 

枚举实现单例模式:

 

 </

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值