假设我有一个线程 T1。我在该线程中创建一个对象,例如Dog
并设置一些属性(name
,color
)等。
然后我线程另一个线程 T2(来自 T1)并将Dog
对象传递给它。此后,T1 不会更改对象的任何属性,甚至不想读取它,而是保留实际引用 ( Dog d
)。
问题:
- 假设 T2 没有更改任何内容
Dog
,Dog Thread 是否安全(从可见性的角度来看。T2 是否总是看到与 T1 设置的名称和颜色相同的名称和颜色)?
假设我有一个线程 T1。我在该线程中创建一个对象,例如Dog
并设置一些属性(name
,color
)等。
然后我线程另一个线程 T2(来自 T1)并将Dog
对象传递给它。此后,T1 不会更改对象的任何属性,甚至不想读取它,而是保留实际引用 ( Dog d
)。
问题:
Dog
,Dog Thread 是否安全(从可见性的角度来看。T2 是否总是看到与 T1 设置的名称和颜色相同的名称和颜色)?线程中的每个操作都可以看到该线程启动之前发生的任何事情。t2.start()
在您的示例中,保证 T2 可以看到 T1 在调用之前所做的所有更改。
这不会使Dog
线程安全,但您对该类的使用是线程安全的。
但是请注意,T1 或 T2 在该点之后所做的任何后续更改都不能保证在其他线程中可见。
参考:JLS #17.4.5:
线程上的 start() 调用发生在已启动线程中的任何操作之前。
Dog
只有当值只是实例变量和易失性时,它才是线程安全的。
如果它们不是易失性的,那么 T2 就有可能读取过时的数据。
只要:
Dog d
当多个线程同时访问对象的属性时,您的实现保证没有竞争条件或者
Dog d
“属性”访问受到竞争条件的保护...您可以认为它是线程安全的。
我想说,现在还不能说你的解决方案是否是线程安全的。因为没有提到数据访问原则或锁。
我怀疑它不是线程安全的!
“狗线安全吗?” 如果它不是不可变的,那么我会说不。
“从可见性的角度来看。T2 是否总是看到与 T1 设置的名称和颜色相同的名称和颜色?” 大概。(注意事情是否不稳定或不同步。
处理此问题的简单方法是对其进行同步。这将使它安全。