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

时间:2016-10-04 06:05:17

标签: java multithreading static non-static

我的班级看起来像这样:

public Class A {

     private static final ObjectMapper mapper = new ObjectMapper();

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

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

3 个答案:

答案 0 :(得分:5)

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

从您提供的代码示例中无法判断,因为我们不知道changeName(text) { this.setState({nameNow: text}) //How can I immediately set the defaultValue='PassMeIn' to nameNow? Because this method would never be called unless text is changed within TextInput } sendOff() { //Would like to access the defaultValue='PassMeIn' here whenever sendOff() is called. How can I? } render() { return ( <View> <TextInput defaultValue='PassMeIn' onChange={this.changeName} value={this.state.nameNow} /> <TouchableHighlight onPress={this.sendOff}/> <Text>Button</Text> </TouchableHighlight> </View> ) } 是什么。

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

如果您不确定,可以:

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

在JVM上创建对象非常便宜(除非他们执行昂贵的操作,如扫描类路径等)。

答案 1 :(得分:0)

每个类加载器都有一个静态变量副本,它加载了这个类。这或多或少意味着每个过程,但是你需要意识到差异。

E.g。当两个web-app捆绑相同的类时,该类将被加载两次,因此具有相同静态字段的两个副本。

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

答案 2 :(得分:0)

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

喜欢:

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