javaBean中的属性变量为什么不用volatile修饰?

        经常在面试中会问到volatile关键字的作用,常见的回答一定都是两个作用:1.保证内存可见性、2.防止指令重排序。如果问到volatile的使用场景,一般也会说多线程并发访问某个的属性变量的时候,为了防止变量更改后不可见添加volatile关键字来修饰这个变量。以上是比较标准的面试问答。

        那么如果我是面试官我可能会追问一下,我们经常在多线程并发编程的场景中,经常使用javaBean。那么我们在javaBean的属性一般来说要不要添加volatile呢?对于这个问题的讨论网上应该很少看到,一般来说候选人都会显得比较犹豫不太确定,往往得到的回答是应该添加volatile,但是继续追问平时在开发的场景中写javaBean对象的时候会给每个属性都添加volatile关键字吗?一般得到都是否定的答案。那么逻辑上就显得比较矛盾,难道平时用的javaBean会因为没有给每个属性添加volatile关键字,导致多线程并发编程的情况下会出现不可见的隐患吗?

        其实这个问题是比较有欺骗性的,因为之前问了volatile的作用,而后续引申出此问题,往往会陷入到之前volatile解决多线程间可见性的思维惯性当中。而这个问题因为网上很少人讨论(我个人还没看过网上有人讨论,这个问题是我自己想的),一般仅仅背八股没有思考很容易落入陷阱中。

        那么接下来我们讨论一下这个问题,这个问题其实和volatile本身关系不大。我们先看一个标准的javaBean是什么形式。类属性都是私有的变量,对属性的访问和赋值都是通过getter/setter方法来操作。那么不管是不是并发场景下,外部都不能直接访问和操作属性本身,都只能通过getter/setter方法来操作,而java语言中,getter方法返回,setter的入参都是传值。所以外部不管有多少个线程拿到的都是与javaBean属性变量的副本,而不是属性变量本身。这种情况下其实根本不是并发场景下对共享的变量操作。此外因为我们无法直接操作属性,而是通过setter方法来对属性进行赋值,每个方法执行的过程中其实是在线程栈中新加入了一个栈帧,而setter方法执行完毕之后,栈帧出栈后,对类属性的操作都会同步到主存中,同理后续getter方法访问的时候也会从主存中读取数据。所以通过方法来读取和设置类属性天然具备可见性,自然我们在平时的开发中也就不会为javaBean中每个属性加一个volatile的关键字了。

      最后补充一下,因为通过getter方法得到只是属性的副本,那么在并发中如果要严格保证对javaBean属性的操作顺序,就需要额外通过锁来控制,如果想对类属性做原子操作,还要自己包装一个方法加上synchronized来实现原子的操作。

     以上就是我对javaBean中的属性变量为什么不用volatile修饰分析的全部内容,希望能给大家带来帮助。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wp500

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值