Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 种族状况:从有害到无害_Java_Concurrency - Fatal编程技术网

Java 种族状况:从有害到无害

Java 种族状况:从有害到无害,java,concurrency,Java,Concurrency,我采用以下竞赛条件的定义: 竞争条件是一种情况,在这种情况下,运行多个并发进程(出于这些目的,一个线程也被建模为一个进程,在不同的机器上运行的进程也是如此)将产生不同的结果,这取决于操作顺序的(未指定,通常不可指定)细节 现在考虑以下样本: 然而,最危险的竞争条件涉及对共享数据结构的访问。如果 两个线程同时更新相同的数据结构,更改可能会被忽略 部分由一根线制成,部分由另一根线制成。数据结构的内容 然后会变得乱码,这将混淆稍后访问它的线程,从而导致 让他们崩溃 显然,此示例包含有害的竞争条件 有一

我采用以下竞赛条件的定义:

竞争条件是一种情况,在这种情况下,运行多个并发进程(出于这些目的,一个线程也被建模为一个进程,在不同的机器上运行的进程也是如此)将产生不同的结果,这取决于操作顺序的(未指定,通常不可指定)细节

现在考虑以下样本:

然而,最危险的竞争条件涉及对共享数据结构的访问。如果 两个线程同时更新相同的数据结构,更改可能会被忽略 部分由一根线制成,部分由另一根线制成。数据结构的内容 然后会变得乱码,这将混淆稍后访问它的线程,从而导致 让他们崩溃

显然,此示例包含有害的竞争条件

有一种解决方案可以避免这种有害的竞争状况:

诀窍是强制线程一次访问一个数据结构,即所谓的 互斥,这样每个线程都可以完成其更新并离开 结构处于下一个线程的一致状态

现在根据上述定义,在上述解决方案中仍然存在一个竞态条件:

若线程A首先进行更改,则共享数据结构的最终内容由线程B填充;若线程B首先进行更改,那个么共享数据结构的最终内容将由线程A填充

但现在这是一个无害的种族状况

从这个样本中,我得到以下结论:

种族状况是有害的,当且仅当它是可以避免的


我不确定上述结论的两个方向或一个方向是正确的还是错误的。那么,是否有任何样本可以反驳这一结论?

您在这里遗漏了一个非常重要的点。数据结构上的任何操作都是在几个周期内进行的,例如,除了给出一个非常基本的步骤

第一步。检索变量的当前值 第二步。将所需数字添加到变量的值 第三步。存储变量的值

在寄存器级别,您可以看到更多的步骤。但关键是,通过锁定变量/数据结构的访问来避免竞争条件意味着只有一个线程可以读/写该数据结构。其他线程将不允许读取数据结构,一旦第一个线程完成所有周期,它将允许其他线程进行更改

线程要做的第一件事是在数据结构没有被任何人锁定的情况下获取锁。然后它做阅读/写作的事情

所以,如果您正确地实现了锁,就不应该存在任何竞争条件

当两个或多个线程可以在同一数据结构中进行更改时,就存在争用情况,如果不能通过锁或其他机制避免这种情况,则可能是有害的。

你是对的

竞态条件-当多个线程访问同一资源时出现。
导致竞争条件的代码段称为临界段。 请注意,当我们试图避免竞争条件时,会发生死锁

您可以通过创建线程安全代码来避免争用条件

  • 局部变量

    局部变量存储在每个线程自己的堆栈中。这意味着线程之间永远不会共享局部变量

  • 本地对象引用

    所有对象都存储在共享堆中,但如果本地创建的对象从未逃逸创建它的方法,则它是线程安全的

  • 使成员字段易变、最终和私有

但是,如果您希望共享一个变量,并且仍然以同步的方式控制它的访问。您可以通过以下方式进行操作

  • 使用显式锁(和条件变量)
  • 使用同步(隐式锁)
这仍然不能保证哪个线程先访问哪个线程,然后访问哪个线程。 对于这种线程控制,使用信号

它可以通过多种方式实现

  • 通过共享对象发送信号
  • 忙等
  • wait()、notify()和notifyAll()
  • 错过信号
  • 虚假唤醒
    • 我不同意。当你不想改变时,无论改变是否可以避免,它都是“有害的”

      显然,当两个进程并行运行时,总是会有竞争在继续改变数据,因此状态的最终结果也可能取决于竞争


      但是当谈到比赛条件时:当比赛过程可能破坏数据的一致性时,就会出现有害的比赛条件。

      这与您的大多数其他问题的主题非常相似。出于好奇,你在写论文吗?可能是