可见性、原子性和有序性
2020-05-22 16:12:04来源:博客园 阅读 ()
可见性、原子性和有序性
1 缓存导致的可见性问题
一个线程对共享变量的修改,另一个线程可以立即看到,这称之为可见性。
Java内存模型规定所有的变量存储在主内存中。每个线程都有自己的工作内存,线程在工作内存中保存了使用到的主内存中变量的副本拷贝,线程对变量的操作必须在工作内存中进行,不能直接读写主内存中的变量。不同线程之间无法访问对方工作内存的变量。线程之间共享变量值的传递均需要通过主内存来完成。
当线程1对共享变量A进行修改之后,线程2的工作内存中A可能还不是最新的值。这时候线程1的操作对线程2就不具有可见性。
2 线程切换带来的原子性问题
我们把一个或者多个操作在CPU执行期间不被打断的特性成为原子性。
Java中的一条语句,在翻译为机器码之后,可能对应的是多个指令。
比如:i++这个操作至少需要3条指令;
- 把 i 的值从内存=加载到寄存器;
- 执行+1操作;
- 把值写入内存;
假如 i=0,两个线程同时执行该操作,可能线程1执行完第一步,就切换到线程2执行,本来两个线程各执行一次后 i 的值应该为 2 ,此时就出现 两次递增操作后值为 1 的现象;
3 编译优化带来的有序性问题
Java程序中,如果在本线程中观察,所有的操作都是有序的;如果在另一个线程观察,所有的操作都是无序的。前半句指的是线程内表现为串行的语义,后半句指的是指令重排序和主内存和工作内存同步延迟的问题。
为了充分利用处理器的性能,处理器会对输入的代码进行乱序执行。在计算之后将乱序执行的结果重组,并保证该结果和顺序执行的结果一致,但是并不保证程序中各个语句的计算顺序和输入代码的顺序一致。Java虚拟机也有类似的指令重排序优化。
比如:Object obj = new Object(),
这条语句对应的指令为:
- 分配一块内存M;
- 在M上初始化 Object 对象;
- 将M的地址赋值给 obj;
计算机经过优化后可能先执行第三步,再第二步,如果执行完第三步后切换到别的线程,若此时访问该变量则会发生空指针异常;
原文链接:https://www.cnblogs.com/tianzg/p/12940366.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:JDK(JAVA环境)安装
- 学妹教你并发编程的三大特性:原子性、可见性、有序性 2020-05-18
- 高级java必须清楚的概念:原子性、可见性、有序性 2020-05-13
- 【漫画】JAVA并发编程三大Bug源头(可见性、原子性、有序性) 2020-05-07
- Java自学-多线程 原子访问 2020-03-08
- JUC中的原子操作类及其原理 2020-01-30
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash