只需一步,快速开始
主题 809|帖子 809|积分 2427
文章整理自 博学谷狂野架构师
如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖性。数据依赖分下列三种类型:
上面三种情况,只要重排序两个操作的执行顺序,程序的执行结果将会被改变。
as-if-serial语义的意思指:不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变。编译器,runtime 和处理器都必须遵守as-if-serial语义。
上面三个操作的数据依赖关系如下图所示:
根据happens- before的程序顺序规则,上面计算圆的面积的示例代码存在三个happens- before关系:
现在让我们来看看,重排序是否会改变多线程程序的执行结果。请看下面的示例代码:
答案是:不一定能看到。
注:本文统一用红色的虚箭线表示错误的读操作,用绿色的虚箭线表示正确的读操作。
下面是操作3和操作4重排序后,程序的执行时序图:
当程序未正确同步时,就会存在数据竞争。java内存模型规范对数据竞争的定义如下:
JMM对正确同步的多线程程序的内存一致性做了如下保证:
顺序一致性内存模型是一个被计算机科学家理想化了的理论参考模型,它为程序员提供了极强的内存可见性保证。顺序一致性内存模型有两大特性:
顺序一致性内存模型为程序员提供的视图如下:
为了更好的理解,下面我们通过两个示意图来对顺序一致性模型的特性做进一步的说明。
现在我们再假设这两个线程没有做同步,下面是这个未同步程序在顺序一致性模型中的执行示意图:
下面我们对前面的示例程序ReorderExample用监视器来同步,看看正确同步的程序如何具有顺序一致性。
当单个内存操作不具有原子性,将可能会产生意想不到后果。请看下面示意图:
本文由传智教育博学谷狂野架构师教研团队发布。 如果本文对您有帮助,欢迎关注和点赞;如果您有任何建议也可留言评论或私信,您的支持是我坚持创作的动力。 转载请注明出处!
您需要 登录 才可以下载或查看,没有账号?立即注册
使用道具 举报
本版积分规则 发表回复 回帖并转播
飞不高