解释一个奇怪的并发现象
来源:互联网 发布:淘宝10公斤和面机价格 编辑:程序博客网 时间:2024/06/06 04:33
我们先看一段多线程访问数据的代码例子:
public class Test1 { private int a=1, b=2; public void foo(){ // 线程1 a=3; b=4; } public int getA(){ // 线程2 return a; } public int getB(){ // 线程2 return b; }}
上面的代码,当线程1执行foo方法的时候,线程2访问getA和getB会得到什么样的结果?大多数朋友应该能回答下面三种情况:
// 都未改变
a=1, b=2
// 都改变了
a=3, b=4
// a改变了,b未改变
a=3, b=2
那么有没有可能产生下面这种可能呢:
a=1, b=4 // b改变了,a未改变
估计会产生一种这样的疑问:怎么可能 b=4语句会先于 a=3 执行呢?其实这是一个多线程之间内存可见性(Visibility)顺序不一致的问题。有两种可能会造成上面的答案:
1) Java编译器的重排序(Reording)操作有可能导致执行顺序和代码顺序不一致。
2)从线程工作内存写回主存时顺序无法保证。
先简单解释下第一点:
假设代码有两条语句,代码顺序是语句1先于语句2执行;那么只要语句2不依赖于语句1的结果,打乱它们的顺序对最终的结果没有影响的话,那么真正交给CPU去执行时,他们的顺序可以是没有限制的。可以允许语句2先于语句1被CPU执行,和代码中的顺序不一致。
从例子中看到的两条赋值语句,并没有依赖关系,无论谁先谁后结果都是一样的,所以就可能有Reordering的情况,这种情况下,对于其他线程来说就可能造成了可见性顺序不一致的问题
再接着解释第二点:
先简单认为线程在修改一个变量时,先拷贝入线程工作内存中,在线程工作内存修改后再写回主存(Main Memery)中。
假设例子中Reording后顺序仍与代码中的顺序一致,那么接下来呢?有意思的事情就发生在线程把Working Copy Memery中的变量写回Main Memery的时刻。线程1把变量写回Main Memery的过程对线程2的可见性顺序也是无法保证的。
- 解释一个奇怪的并发现象
- hql一个奇怪的现象
- ifstream一个奇怪的现象
- C++的一个奇怪现象
- 发现ASP的一个奇怪现象
- ASP.NET 2.0的一个奇怪现象~~
- 一个很奇怪的网络现象
- 今天发现一个奇怪的现象?
- Javascript和DOM的一个奇怪现象
- sizeof数组的一个奇怪现象
- c++中 堆的一个奇怪现象
- java Calendar类 一个奇怪的现象
- ie8中一个很奇怪的现象。
- TextView结尾...结束的一个奇怪现象
- 如何解释这个ASP.NET的IsClientConnected奇怪的现象?
- 求救!!!奇怪的现象!
- 奇怪的现象
- noskipws()的奇怪现象!
- jQuery图片放大镜插件jqzoom
- Windows下使用Git Bash上传项目到GitHub
- 截断数组
- jQuery插件flexiGrid的完全使用,附代码下载
- MyEclipse中没有支持的tomcat版本怎么办?
- 解释一个奇怪的并发现象
- 详解如何让MyEclipse具有强大的提示功能
- Jquery ajax跨域访问的问题
- 拉格朗日乘子法的数学基础
- 【前端】前端构建是否需要升级
- andriod实现自己的ioc容器
- JQuery解析xml
- Java调用Oracle存储过程
- eclipse-jee-helios-SR2-win32 下maven插件安装