当多个线程正在访问它时,在非静态方法中使用静态对象是否安全?

Is it safe to use a static object in a non-static method when multiple threads are accessing it?

我的 class 看起来像这样:

public Class A {

     private static final ObjectMapper mapper = new ObjectMapper();

     public String get(String key) {
          JsonNode nod = mapper.readTree(getFromCache(key));
     }
}

多个线程将访问此方法。我需要同步它吗?我需要在方法内移动映射器吗?

这取决于 ObjectMapper 的实施。有关可能的答案,请参阅: Should I declare Jackson's ObjectMapper as a static field?

无法从您提供的代码示例中分辨出来,因为我们不知道 ObjectMapper 是什么。

要找到答案,您需要查看 ObjectMapper 的 javadoc。或者失败,实施。

如果您不确定,您可以:

  • 在方法中创建一个新的ObjectMapper,这样每次都有一个新的对象,
  • 创建一个 ThreadLocal,这样每个线程都有自己的对象

在 JVM 上创建对象的成本非常低(除非它们执行扫描 class 路径等昂贵的操作)。

每个加载此 class 的 class-loader 都有一份静态变量副本。这或多或少意味着每个进程,但是您需要了解其中的区别。

例如当两个网络应用程序捆绑了相同的 class 时,class 将被加载两次,因此具有相同静态字段的两个副本。

如果您需要一个基于线程具有独立值的变量,请查看 ThreadLocal

作为WW。提到它取决于 ObjectMapper.readTree 实现。有多种因素决定该方法是否是线程安全的。

喜欢:

  1. 方法是否同步
  2. 方法是否使用在方法外部声明的变量