java 字符串原子变量,java源码学习(java-src)之原子性、可见性、有序性到底说的是啥?...

如果内容有错误或者您有不同的见解,请关注我。想要思维导图的小伙伴们记得留言哦。

ede4600db90e96fd2ce1276842960bc0.png

【问题】为啥出现这三个名词?

因为:现在计算机处理数据可以并发,也就会出现多个线程操作一个数据(代码块)的情况。多核CPU在处理数据的时候会将内存的数据复制到高速缓存中,然后再处理数据,处理之后在写回到主内存中。各个线程都复制了一份数据,又写回内存,内存的数据自然就会有可能变得不一致。比如A线程获取a的值放在自己的内存中,改了一下,还没放回到主内存时,B也读取了a,也操作了。此时A放回去,之后B不知道A刚刚修改了。这三个改变都是基于多线程的,也就说在多线程下会有这三个问题要解决。

原子性(Atomicity)是多线程之间保证只能有一个线程在同一个时间执行。

【释义】一个或多个操作,要么全部执行且在执行过程中不被任何因素打断,要么全部不执行。

这句话经常见但是你会发现,什么是一个或多个操作,理解起来比较费劲,无非就是读写数据嘛,其实如果说我们在读写一个数据的时候,这个读写实际上是两个操作(读和写),那么原子性就是两个操作一块执行,我读了就是我写,你读了我就不写了或者连读也不读。像java源码中:AtomicInteger能保证int这个值的原子性,而synchronize{int a,String b}能保证整个代码块的原子性。

可见性(Visibility)是多线程之间保证变量可以相互读写

【释义】当一个线程修改了变量的值,其他线程能够立即获取到修改之后的值。就是说线程A修改了一个变量之后,线程B马上读取应该就能拿到最新的值。怎么保证这个可见性呢?使用volatile、synchronized、lock、atomicXXX类来保证。

【volatile】

线程在读取数据的时候,不是从缓存中读取了,而是直接从内存(共享内存)中读取这个值。也就是说被volatile修饰的变量在内存中所有的线程在使用时是先读,都不在去缓存一份副本。

【注意】

volatile只能保证可见性,不能保证原子性。读取块,但是写的时候慢(需要执行内存屏障指令,防止指令重排序。

【synchronized】

这货也可以保证可见性,在加锁时清空工作内存的共享变量的值,从而从内存中重新读取共享变量的值。在解锁时需要将工作内存中的共享变量的值写入到主内存。来保证主内存中的数据都是最新的,同时也保证了可见性。

【Lock】

这货为啥能保证可见性呢?因为该类继承了AbstractQueuedSynchronizer,这个类中使用的是state这个变量,而这个变量是volatile 修饰的。

/**

* The synchronization state.

*/

private volatile int state;

【指令重排序】

指令重排序不会破坏依赖关系,它会保证执行结果总是一样。指令重排序是在多线程执行程序时为了提高CPU使用率才会去优化和重排序指令(代码)。

我们在使用volatile修饰的变量的时候,这个代码执行到此处,会先去主内存(共享内存)中读取数据,然后在继续操作,同理synchronized也会防止指令重排序。

为什能防止指令重排序呢?

我觉得就是因为我们在读取volatile修饰的变量的时候是从主内存读取的,而不是自己的线程副本中,在使用该变量时CPU不知道当前值的内容或者已被通知该值已经改变,所以不能重排序。

有序性(orderly)是多线程之间在在执行同一个代码的时候有顺序

【释义】程序按照先后顺序执行,就是说代码在多个cpu上执行,要按照一定顺序执行,A线程执行到此处,其他的线程就得等着A执行完才能执行,就是让代码有顺序的执行。别瞎搞。

【理解】CPU重排序其实是最大利用CPU的资源,不能让CPU闲着,但是如果你让CPU能按照顺序执行,CPU的资源肯定会浪费,因为没有拿到锁的线程都睡着呐。

synchronized保证了有序性(根据as-if-serial语义(就好像是顺序执行一样),无论编译器和处理器怎么优化也好,重排序指令也好,单线程结果一定是正确的。)有了这个sync整个世界都是顺序的,乖的很。

其他说明:

可见性:缓存一致性协议

当CPU对变量进行写操作时发现,变量是共享变量,那么就会通知其他CPU中将该变量的缓存行设置为无效状态。当其他CPU在操作变量时发现此变量在的缓存行已经被设置成了无效,那么就会去主内存中重新读取最新的变量。

内存屏障:一组CPU指令,用于实现对内存操作的顺序限制。

Java编译器,会在生成指令系列时,在适当的位置会插入内存屏障来禁止处理器对指令的重新排序。

如果内容有错误或者您有不同的见解,请关注我。想要思维导图的小伙伴们记得留言哦。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值