【发布时间】:2013-09-03 10:08:29
【问题描述】:
我正在尝试确定是否需要在我编写的几个关键类中担心线程安全。我已经阅读了几篇文章/现有的 SO 问题,并且我一直看到相同的、反复出现的线程安全定义:
线程安全意味着对象或类的字段始终保持有效状态,正如其他对象和类所观察到的那样,即使在多个线程同时使用时也是如此。
好的。我有点明白了。但是我在这里遗漏了一个很大的难题:
只有当一个类的相同实例被多个线程使用,或者只有当任何 2+个实例被使用时,线程安全才会发挥作用?正在使用?
示例 #1:
假设我有一个不包含静态方法或字段的 Dog 类,假设我有 5 个不同的 Dog 实例,它们从 5 个不同的线程内部进行操作。我需要关注线程安全吗?我会说“不”,因为没有静态字段/方法,并且每个线程都有自己的 Dog 实例,其状态独立于其他 4 个实例而存在。 (1) 这是正确的吗?如果不是,为什么?
示例 #2:
现在假设我向Dog 添加了一个静态方法:
public void woof() {
this.isWoofing = true;
}
public static void makeWoof(Dog dog) {
dog.woof();
}
我现在需要关注线程安全吗?每个线程都有自己的Dog 实例,但现在它们共享相同的静态makeWoof() 方法,这会改变它正在操作的Dog 的状态。我还是说“不”。 (2) 这是正确的吗?如果不是,为什么?
鉴于这两个例子,在我看来,线程安全只是当多个线程在一个类的同一个实例上运行时才会出现问题。但是,当您为每个线程提供自己的实例时,似乎我可以对那个实例做任何我想做的事情,而不必担心其他线程内部发生了什么。 (3) 这是正确的吗?如果不是,为什么?他们有任何例外吗?提前致谢!
【问题讨论】:
-
将静态字段(属于类的那些)视为“类实例”的字段,就像它们有时在其他语言中被称为对象一样(想到 smalltalk)。由于类是全局的,因此每个线程都可以访问并可能修改它们。否则,相同的规则适用于所有其他对象。但是,如果这些不是您示例中的静态字段,则静态方法无法修改它们。
标签: java multithreading concurrency thread-safety static-methods