2017-08-11 83 views
2

我写一些代码,其中爪哇 - 同一个对象,不同的变量,多线程

class A { 
    Integer x; 
    String y 
} 

我创建了一个对象,我把它传递给2级运行的线程。第一个线程更新值x,而第二个更新值y。

有没有这种情况可以打破?我的意思是,如果有两个线程更新同一对象的不同变量,是否会出现竞态条件?

+2

为什么你需要单个对象呢?将不同的对象传递给不同的线程 –

+1

是的,有很多这种情况可能会中断。你需要阅读http://jcip.net/ – Oleg

+1

哪个线程是读取数据的? –

回答

0

不,它会正常工作。只要任何给定的变量只被一个线程更新(在其他线程读取该变量时有一些条件),你就没事了。

它可能不是最理解的设计,取决于你在做什么 - 另外,正如我上面提到的,不要指望从另一个线程可靠地读取这些变量,如果你想要看看原子对象或易挥发。 (原子会从多个线程写入更快,挥发性仍可能更好,如果你只是从一个线程写,别人读)

+2

这个答案就像一个handwave:“其他线程读取变量的一些条件”是最重要的部分!在所描述的场景中可能会出现很多非显而易见的行为,具体取决于'x'和'y'被读取的位置,这是这里的重要部分。 –

0

多线程不仅是比赛条件下,它也是关于通过
jsr-133制定存储可视性如果您想了解java中的并发性,您绝对必须学习这些知识。

有些情况下,你的代码可以打破可能很多方面,一个明显的例子是,如果你在线程创建的对象在线程C-线程B和Y的变化X你可能永远不会看到线程A这些变化

一些代码来说明:

A a = new A(); 
a.x = 0; 

Thread t1 = new Thread(() -> { 
    while (true) { 
     a.x = 1; 
    } 
}); 

Thread t2 = new Thread(() -> { 
    a.y = "a"; 
}); 

t1.start(); 
t2.start(); 

while(a.x == 0) { 
} 

System.out.println("might never get here"); 

一个可能的解决办法是让X和Y挥发性

class A { 
    volatile Integer x; 
    volatile String y; 
} 

这将确保所有线程看到改变x和y但您仍然需要确保A的实例已安全发布。

+0

@BillK“如果作者仅仅是从两个线程写入不同的变量,那么他很好”**绝对不是!!! **不确保写入将被正确地看到,他将以意外的行为和不正确的值结束。我制定了一个符合他的问题和休息的场景(至少可以休息,实际上很难看到它发生)。 – Oleg