当多个线程正在访问它时,在非静态方法中使用静态对象是否安全?
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
实现。有多种因素决定该方法是否是线程安全的。
喜欢:
- 方法是否同步
- 方法是否使用在方法外部声明的变量
我的 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
实现。有多种因素决定该方法是否是线程安全的。
喜欢:
- 方法是否同步
- 方法是否使用在方法外部声明的变量