2013-05-15 33 views
3

说我有一个线程T1。我在该线程中创建了一个对象,例如Dog和设置一些属性(namecolor)等MultipleThreads和同步线程可见性

然后我线程另一个线程T2(从T1)和Dog对象传递给它。在此之后,T1不会更改对象的任何属性,甚至不想读取它,但会保留到实际参考(Dog d)。

问:

  1. 假设T2不Dog改变什么,狗是线程安全的(从知名度待机点将T2总是看到由T1设置相同的名称和颜色。)?
+0

两个线程都不改变Dog实例,它绝对是线程安全的 – hoaz

+0

仅仅因为你选择不改变对象并不意味着它是线程安全的。使用这个逻辑,* everything *将是线程安全的。您似乎在谈论Java的线程缓存而不是线程的可见性*安全* –

回答

1

Dog是线程安全只有当值只是实例变量震荡。

如果它们不是不稳定的,T2有可能读取陈旧的数据。

+4

在OP示例中不需要volatile。 – assylias

+0

你能详细说明一下吗?如果您没有将该变量标记为volatile,则不同的线程总是会导致读取缓存而不是读取正确的值。 –

+1

如果你有这个序列:[在T1]:'dog.setName(“doggy”); T2.start();'和[在T2]'println(dog.getName());' - 你有保证在T2中打印'doggy'或者可能有更近期的值。这是因为't2.start()'作为内存屏障,阻止T2读取较旧的值。 – assylias

-1

“狗线程安全吗?”如果它不是一成不变的,那么我会说不。

“从知名度的角度来看,T2总是会看到与T1所设定的名称和颜色相同的颜色吗?”大概。 (注意,如果事情不挥发或同步。

简单处理这个办法是在其上同步。这将使它的tHead安全。

+0

可变性不排除线程安全。如果你有易变的变量,它们是线程安全的,因为你将无法读取陈旧的数据。如果值是不可变的,并且您对它们进行计算,那么保证线程安全性就更简单了。 –

+0

这就是为什么我说“可能”,但没有任何信息给狗的内部细节。我不想推测。 – Nick

+0

OP明确表示Dog(及其属性)在创建线程T2后没有更改。因此,对于这种特殊情况,Dog在创建T2之后变得不可变(不是真正意义上的),因此线程安全。 – Parvez

2

在一个线程中的每个动作可以看出,线程之前不管发生什么事情开始在你的榜样,T2是保证看到T1进行的所有更改t2.start()被称为前。

这不会让Dog线程安全的,但你的这个类的使用是线程安全的。

然而要注意之后由T1或T2进行的任何后续更改点不能保证从其他线程可见。


参考:JLS #17.4.5

调用开始()上线之前发生在启动线程的任何行动。

0

只要:

  • 您的实现担保由多个线程同时访问您Dog d对象的属性

  • Dog d时是免费的竞态条件“ s属性的访问受到保护,免受竞争条件的影响

...你可以认为它是线程安全的。

我现在说现在不可能说你的解决方案是否是线程安全的。因为没有提及数据访问原理或锁。

我怀疑它不是线程安全的!