JVM如何在内部处理竞争条件?

时间:2014-11-28 16:27:06

标签: java multithreading jvm race-condition

如果多个线程尝试更新同一个成员变量,则称其为竞争条件。但是我更感兴趣的是,如果我们不通过使它同步或其他东西在我们的代码中处理它,JVM如何在内部处理它?它会挂起我的程序吗? JVM将如何应对?我认为JVM会暂时为这种情况创建一个同步块,但我不确定究竟会发生什么。

如果你们有任何见解,那就很高兴知道。

5 个答案:

答案 0 :(得分:17)

准确的术语是数据竞赛,它是竞争条件的一般概念的特化。术语数据竞赛是一个官方的,精确指定的概念,这意味着它来自对代码的形式分析。

获得真实情况的唯一方法是去学习Java语言规范的内存模型章节,但这是一个简化的视图:每当你进行数据竞争时,几乎不能保证结果和读取线程可以看到任何已写入变量的值。其中还有唯一的保证:线程将观察到“超薄空气”值,这是从未写过的。好吧,除非你正在处理longdouble s,否则你可能会看到撕裂的写作。

答案 1 :(得分:5)

也许我错过了什么,但有什么可以处理?还有一个线程会先到达那里。根据哪个线程,该线程将只更新/读取某个变量并继续执行下一条指令。它不能神奇地构建一个同步块,它并不真正知道你想做什么。换句话说,所发生的事情将取决于“种族”的结果。

注意我并没有深入到较低级别的东西,所以也许我不完全理解你的问题的深度。

答案 2 :(得分:2)

Java提供synchronizedvolatile来处理这些情况。正确使用它们可能会令人沮丧,但请记住,Java只暴露了现代CPU和内存架构的复杂性。替代方案是始终谨慎对待,有效地同步所有会破坏性能的东西;或忽略问题,并提供任何线程安全。幸运的是,Java在java.util.concurrent包中提供了出色的高级构造,因此您可以经常避免处理低级别的东西。

答案 3 :(得分:1)

简而言之,JVM 假设代码在将其转换为机器代码时没有数据争用。也就是说,如果代码未正确同步,则Java语言规范仅提供有关该代码行为的有限保证。

大多数现代硬件同样假设代码在执行时没有数据竞争。也就是说,如果代码未正确同步,则硬件仅对其执行结果提供有限保证。

特别是Java语言规范guarantees以下仅在没有数据竞争的情况下:

  • 可见性:读取字段会产生最后分配给它的值(不清楚哪个写入 last ,并写入长变量或双变量need not be atomic
  • 排序:如果写入是可见的,那么它之前的任何写入都是可见的。例如,如果一个线程执行:

    x = new FancyObject();
    

    只有x的构造函数完全执行后,另一个帖子才能读取FancyObject

在数据竞争的情况下,这些保证是无效的。读取线程可能永远不会看到写入。也可以看到x的写入,而不会看到逻辑上先于x写入的构造函数的影响。如果不能做出这样的基本假设,那么该计划是不正确的。

然而,数据竞争不会损害Java虚拟机的完整性。特别是,JVM不会崩溃或停止,并且仍然保证内存安全(即防止内存损坏)和certain semantics of final fields

答案 4 :(得分:0)

JVM会很好地处理这种情况(即它不会挂起或抱怨),但你可能得不到你喜欢的结果!

当涉及多个线程时,java变得非常复杂,甚至看起来非常正确的代码也会被严重破坏。举个例子:

public class IntCounter {
    private int i;

    public IntCounter(int i){
         this.i = i;
    }

    public void incrementInt(){
        i++;
    }

    public int getInt(){
        return i;
    }
}

在很多方面存在缺陷。

首先,假设i当前为0,并且线程A和线程B几乎同时调用incrementInt()。有一种危险,他们都会看到我是0,然后两者都增加1然后保存结果。所以在两次通话结束时,我只有1,而不是2!

这是代码的竞争条件问题,但是还有其他与内存可见性有关的问题。当线程A更改共享变量时,无法保证(没有同步)线程B将看到更改!

因此,线程A可以增加100倍,一小时后,线程B,调用getInt(),可能会将i视为0,或100或其中任何位置!

如果你正在深入研究java并发性,唯一能做的就是阅读Brian Goetz等人的Java Concurrency in Practice。 (好吧,可能有其他好方法可以了解它,但这是一本由Joshua Bloch,Doug Lea和其他人撰写的好书)