Bean中的CHM变动是否需volatile关键字确保线程安全?

摘要:你好呀,我是歪歪。 事情是这样的,前几天有一个读者给我发消息,说他面试的时候遇到一个奇形怪状的面试题。 歪师傅纵横面试界多年,最喜欢的是奇形怪状的面试题。 可以说是见过大场面的人,所以让他描述一下具体啥问题。 据他的描述,这道面试题是这样的
你好呀,我是歪歪。 事情是这样的,前几天有一个读者给我发消息,说他面试的时候遇到一个奇形怪状的面试题。 歪师傅纵横面试界多年,最喜欢的是奇形怪状的面试题。 可以说是见过大场面的人,所以让他描述一下具体啥问题。 据他的描述,这道面试题是这样的: 在多线程环境下使用 ConcurrentHashMap 时,是否需要将其声明为 volatile 以确保线程安全? 呃... 这个题... 有点意思... 简单盘一盘 这个题听起来确实有点奇奇怪怪的,多线程、ConcurrentHashMap(后续文中用 CHM 代替)、volatile、线程安全... 乍一听有一种全都是我熟悉的技术点,但是组合在一起,突然有点不认识了的陌生感。 但是如果你真的对上面这几个技术点达到了熟悉的程度,那么简单梳理一下之后,你又会觉得线索太多,甚至有点不知道从何说起。 先梳理清楚两个关键点: CHM 是干啥的?volatile 又是干啥的? 首先,CHM 是八股中老大哥了,一般它和 HashMap 会在面试环节成对出现。 比如这样式儿的:HashMap 不是线程安全的,那我们应该怎么办呢? 然后 CHM 就噼里啪啦一大堆开始背诵起来了。 但是在这篇文章中,关于 CHM 我们需要注意的就一个点: CHM 是线程安全的,但是它的线程安全仅限于方法内部的操作。 然后,volatile 是干啥的? 这种老八股应该是张口就来: volatile 可以保证变量的可见性,即一个线程修改了被 volatile 修饰的变量,其他线程能立即看到新值。 这里画个重点:变量。 如果要把 CHM 和 volatile 牵扯到一起,那么他们就需要对齐一下颗粒度:CHM 需要是一个变量。 当 CHM 在程序的引用中会发生变化时,讨论 volatile 才有意义。 所以,这个面试题的答案也就呼之欲出了。 答案就是:得结合代码,看具体场景,分两种情况去讨论。 第一种情况是 CHM 的引用不会发生变化,就不需要加 volatile。 比如下面这种写法: private static final ConcurrentHashMap<String, String> chm = new ConcurrentHashMap<>(); 这里的 final 已经保证引用不可变,无论多少个线程在同时操作这个 CHM,都能确保看到的始终是同一个对象。 至于线程安全问题,CHM 内部的方法自会处理好并发问题。 第二种情况是 CHM 的引用会变,比如这样的代码逻辑: privatevolatileConcurrentHashMap<String,String>cache=newConcurrentHashMap<>(); publicvoidupdateCache(){ ConcurrentHashMap<String,String>newCache=newConcurrentHashMap<>(); //填充新数据... cache=newCache; } 因为我们程序中有把 newCache 赋值给 cache 的操作,而这个 cache 可能又不只是一个线程在操作。 所以这个场景下,就需要使用 volatile,保证当前线程对 cache 操作之后,其他线程能立刻看到新引用。 从而保证了线程安全。 现在,我们再回过头去看这个问题,应该就清晰很多了: 在多线程环境下使用 ConcurrentHashMap 时,是否需要将其声明为 volatile 以确保线程安全? 这个问题确实是有点陷阱的,不能直接回答需要或者不需要。 需要面试者结合自己的理解,去分析出不同的场景,得到上面的回答。 想到另一个题 在分析上面这个问题的时候,我又联想到了另外一个经典的面试题。 问:Spring 的 Bean 是否是线程安全的? 我个人认为这两个题的相似程度算是非常高的。 为啥这样说呢? 我们一起分析一波。 首先,我们搞个示意代码: @Controller publicclassTestController{ privateintnum=0; @RequestMapping("/test") publicvoidtest(){ System.out.println(++num); } @RequestMapping("/test1") publicvoidtest1(){ System.out.println(++num); } } TestController 就是在 Spring 中托管的一个 Bean。
阅读全文