java - Java 线程安全适用于类的所有实例还是仅适用于共享实例?

标签 java multithreading concurrency thread-safety static-methods

我正在尝试确定是否需要担心我编写的几个关键类中的线程安全性。我已经阅读了几篇文章/现有的 SO 问题,并且我一直看到相同的、重复出现的线程安全定义:

Thread Safety means that the fields of an object or class always maintain a valid state, as observed by other objects and classes, even when used concurrently by multiple threads.

好的。我有点明白了。但是我在这里遗漏了一个很大的难题:

线程安全是否仅在多个线程使用一个类的相同实例时发挥作用,或者仅当任何 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) 这是正确的吗?如果不是,为什么?

鉴于这 2 个示例,在我看来,只有当多个线程在一个类的相同实例 上运行时,线程安全才是一个问题。但是当你给每个线程它自己的实例时,似乎我可以对那个实例做任何我想做的事情,而不用担心其他线程内部发生的事情。 (3) 这是正确的吗?如果不是,为什么?他们有异常(exception)吗?提前致谢!

最佳答案

您关于线程安全的假设是正确的。它归结为同一 instance 上的字段/状态被多个线程修改。

在您的第一个问题中,所有线程都操纵它们自己的 Dog 实例,因此该方法是线程安全的。

在第二个问题中,实例被传递到静态方法中,因此您再次使用该类的不同实例。如果 Dog 类包含静态字段并且静态方法操作那些不是线程安全的字段,但非最终静态字段实际上永远不是线程安全的。

关于java - Java 线程安全适用于类的所有实例还是仅适用于共享实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18536961/

相关文章:

c# - 使用 BlockingCollection<T> : OperationCanceledException, 有更好的方法吗?

java - 不稳定的 StampedLock.unlock(long) 行为?

java - 如何从 ListView 获取所选项目值

java - 将 PostgreSQL JSON 列映射到 Hibernate 实体属性

iOS 无效行更新异常

java - 使用 warble 将带有 Rubeus 和 Swing 的 JRuby 脚本打包到 jar 中后退出

java - 为什么我的代码中看起来有两个线程正在访问一个锁?

java - 小数或 double 之间的转换

java - 如何修复接收对象数组的静态泛型方法

java - Android:将网页的HTML读入字符串