草庐IT

java - Java内存模型中具有数据竞争的正确同步程序的示例

coder 2024-03-13 原文

JLS, §17.4.5. Happens-before Order中,它说

A program is correctly synchronized if and only if all sequentially consistent executions are free of data races.



根据Does a correctly synchronized program still allow data race?(Part I)中的讨论,我们得出以下结论:

A program can be correctly synchronized and have data races.



两个结论的组合意味着它必须存在这样的示例:

All sequentially consistent executions of a program are data race free, but the normal executions (executions other than sequentially consistent executions) of such a program contain data race.



经过深思熟虑,我仍然找不到这样的代码示例。那你呢

最佳答案

“程序可以正确同步并具有数据竞争”是不正确的。在该讨论中,assylias的示例未正确同步。从更高级别的功能角度来看,它是正确的-它包含的数据竞争不会表现为错误。这是所谓的“良性”数据竞争,但是在讨论JLS定义时这是无关紧要的。
保证顺序一致执行不包含数据竞争的程序在任何执行中都不会包含数据竞争,无论顺序一致与否。正如JLS所说,

This is an extremely strong guarantee for programmers. Programmers do not need to reason about reorderings to determine that their code contains data races. Therefore they do not need to reason about reorderings when determining whether their code is correctly synchronized. Once the determination that the code is correctly synchronized is made, the programmer does not need to worry that reorderings will affect his or her code.


因此,请注意,出于对程序员的礼貌,正确同步的程序的定义已缩小到仅顺序一致的执行,这为他提供了强有力的保证,即顺序一致的执行是他或她唯一需要推理和执行所有其他执行的命令将自动具有相同的保证。
更新
JMM使用的术语很容易迷失,并且细微的误解会在以后引起深刻的误解。因此,请谨记以下几点:
  • 执行只是一组线程间操作。没有先验顺序。特别是,没有,没有时间顺序

  • 这是一个违反直觉的定义,因此我们必须谨慎对待:每次执行时,我们都必须确保想象一个 Action 包,从不包含任何字符串。每当我们定义偏序时,我们都应该想象几个袋子排列在中。
  • 程序包含执行操作的指令。每个这样的指令可以执行零次或更多次,从而为特定执行贡献零次或更多次独特的 Action ;
  • 执行可能有执行顺序,也可能没有,这是所有 Action 的总顺序;
  • 一个顺序一致的执行是如果所有共享变量都是volatile的,您将获得。这种执行总是有一个确定的执行顺序。
  • 顺序不一致执行是您在程序中的实际执行:涉及非 volatile 变量,并且编译器对读取和写入进行重新排序,有缓存,线程本地存储等。
  • 同步顺序是执行执行的所有同步操作的总顺序。关于执行本身,它仍然是部分顺序的,因为并非所有 Action 都是同步 Action 。最值得注意的是,读写非 volatile 变量。每次执行(无论顺序是否一致)都具有确定的同步顺序;
  • 同样,在为程序的特定执行定义顺序之前,发生,并且作为与程序顺序的同步顺序的传递闭包而派生。

  • 有趣的是,如果所有共享变量都是 volatile 的,则同步顺序将变为总顺序,因此将满足执行顺序的定义。这样,我们从不同的角度得出这样的结论,即该程序的所有执行将顺序一致。
    我已经深入研究了数据争用的定义中的JLS错误:
    “当程序包含两个冲突访问(第17.4.1节),而这些访问没有按事前发生关系进行排序时,就说它包含一个数据争用。”
    首先,不是程序包含数据竞争,而是程序执行。如果回头引用定义Java内存模型的original paper,我们将看到已更正的错误:
    “如果两次访问x和y来自不同的线程,它们会冲突,并且不会按先有先后的顺序排列,则它们会在程序执行中形成数据争用。”
    但是,这仍然使我们对定义为数据竞争的 volatile 变量采取的措施。请考虑以下发生在图表之前的情况:
    Thread W        w1 ----> w2
                    |
                     \
    Thread R     r0 ----> r1
    
    r1观察到写入w1。它之前是另一个读r0,而写之后是另一个读w2。现在注意r0和w1或w2之间没有路径;同样在r1和w2之间。根据定义,所有这些都是数据竞争的示例。
    深入研究,但是,我发现this post on the memoryModel mailing list。它说“一个数据
    种族应定义为对非 volatile 变量的冲突 Action
    “没有按事前发生的顺序进行排序”。只有添加了该漏洞后,漏洞才会被关闭,但这尚未进入JLS的正式发布。

    关于java - Java内存模型中具有数据竞争的正确同步程序的示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12024070/

    有关java - Java内存模型中具有数据竞争的正确同步程序的示例的更多相关文章

    1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

      作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

    2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

      我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

    3. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

      我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

    4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

      我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

    5. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

      我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

    6. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

      我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

    7. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

      我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

    8. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

      我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

    9. java - 等价于 Java 中的 Ruby Hash - 2

      我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

    10. ruby-on-rails - 如何将验证与模型分开 - 2

      我有一些非常大的模型,我必须将它们迁移到最新版本的Rails。这些模型有相当多的验证(User有大约50个验证)。是否可以将所有这些验证移动到另一个文件中?说app/models/validations/user_validations.rb。如果可以,有人可以提供示例吗? 最佳答案 您可以为此使用关注点:#app/models/validations/user_validations.rbrequire'active_support/concern'moduleUserValidationsextendActiveSupport:

    随机推荐