在java中,静态对象线程的返回值是否安全

时间:2012-05-02 03:20:03

标签: java thread-safety

让我们假设一个对象如下:

My Object { 
private String field1 = "";
private  String field2 = "";

/*getters and setters for field1 and field2 */

boolean isField1inDocument (String document) {
      if (document.indexOf(field1) > -1) return true;
      else return false;
 }

}

方法isField1inDcoument线程是否安全?我担心一个线程返回的布尔值可能会与同时执行该方法的另一个线程创建的布尔值发生冲突。馈送到该方法的文档来自单个线程,文档本身不会发生冲突。我知道我可以同步这个方法。我只想弄清楚这是否有必要。

谢谢,

埃利奥特

3 个答案:

答案 0 :(得分:2)

逻辑上,isField1inDocument()的行为仅依赖于文档(您说它仅由线程拥有)和field1的值。你确实有字段1的setter所以你可以想象一个场景,当你的当前线程正在进行isField1inDocument()计算时,field1被另一个线程改变,所以这不是线程安全的。

您可以通过传入field1值来解决此问题,例如:

boolean isField1inDocument (String document, String field1){...

或通过从调用者线程

保存封闭MyObject的私有实例
new MyObject().isField1InDocument(document)

答案 1 :(得分:1)

这不是线程安全的。

原因是它正在访问作为实例变量的field1,其他线程可以在方法内访问时修改field1,导致计算错误。

可以通过多种方式解决此问题,

  • 将field1作为参数的一部分

    boolean isField1inDocument(String document,String field1)

在这种情况下,因为方法存在于Stack上,并且对于每个线程都有一个单独的Stack没有线程交错问题。

  • 同步您的代码,以便只有一个线程可以访问field1,因此field1isField1inDocument的setter方法应该在同一个对象上同步。同步会导致吞吐量下降,因此在执行此操作时必须小心。
  • 如果你可以使field1成为最终版本,在这种情况下它无法初始化并且你对线程安全的关注得到了解决。

答案 2 :(得分:0)

如果你将field声明为final,那么这个方法将成为线程安全的,那么第一个字段就不会被修改