1

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

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 线程安全吗?我担心一个线程返回的布尔值可能会与同时执行该方法的另一个线程创建的布尔值发生冲突。提供给该方法的文档来自各个线程,并且文档本身不会发生冲突。我知道我可以同步这个方法。我只是想弄清楚这是否有必要。

4

3 回答 3

2

从逻辑上讲,isField1inDocument() 的行为仅取决于文档(您说它仅由线程拥有)和 field1 的值。您确实有字段 1 的设置器,因此可以想象在当前线程正在执行 isField1inDocument() 计算时 field1 被不同线程更改的场景,因此这不是线程安全的。

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

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

或者通过从调用者线程中保存封闭 MyObject 的私有实例

new MyObject().isField1InDocument(document)
于 2012-05-02T03:26:12.453 回答
1

不,这不是线程安全的。

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

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

  • 将 field1 作为参数的一部分传递

    boolean isField1inDocument(字符串文档,字符串字段1)

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

  • 同步您的代码,以便只有一个线程可以访问 field1,因此 和 的 setter 方法field1isField1inDocument应该在同一个对象上同步。同步会导致吞吐量下降,因此您在这样做时必须小心。
  • 如果您可以将 field1 设为 final,则在这种情况下,它无法被初始化,并且您对线程安全的担忧得到了解决。
于 2012-05-02T03:25:56.620 回答
0

如果您将字段声明为 final,此方法将成为线程安全的,那么字段一将不会被修改

于 2012-05-02T03:28:49.463 回答