Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
静态对象的返回值在java中是线程安全的吗_Java_Thread Safety - Fatal编程技术网

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

静态对象的返回值在java中是线程安全的吗,java,thread-safety,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 ret

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

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;
 }

}
该方法是否为IsField1索引线程安全?我担心一个线程返回的布尔值可能会与另一个线程同时执行该方法所创建的布尔值发生冲突。提供给方法的文档来自各个线程,文档本身不会发生冲突。我知道我可以同步这个方法。我只是想知道这是否必要

谢谢,


Elliott不,这不是线程安全的

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

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

  • 将字段1作为参数的一部分传递

    布尔值IsField1文档(字符串文档,字符串字段1)

在这种情况下,由于方法位于堆栈上,并且每个线程都有一个单独的堆栈,因此不会出现线程交错的问题

  • 同步代码,以便只有一个线程可以访问field1,因此
    field1
    isField1inDocument
    的setter方法应在同一对象上同步。同步会导致吞吐量降低,因此在执行此操作时必须小心
  • 如果您可以将field1设置为final,那么在这种情况下,它将无法初始化,您对线程安全的担忧也将得到解决

从逻辑上讲,isField1inDocument()的行为只依赖于文档(您说它只属于线程)和field1的值。您确实有字段1的setter,因此可以想象这样一种场景:当当前线程正在进行isField1inDocument()计算时,字段1被另一个线程更改,因此这不是线程安全的

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

boolean isField1inDocument (String document, String field1){...
或者从调用线程中保存封闭MyObject的私有实例

new MyObject().isField1InDocument(document)

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

您对“静态对象”的定义是什么?是否有多个线程调用同一方法,创建该方法的单独实例,以使该方法返回的值保持线程安全?这不是该方法实例的问题,而是该方法访问的数据。因此,您的初始方法是不安全的,因为它正在访问共享数据变量。实际参数(文档)没有问题,如果您关心的是这个问题的话-方法参数是在这个调用的方法范围的上下文中操作的,并且不会与调用相同方法的另一个线程交互,即使在同一个实例上,如果多个线程可以对同一个数据执行操作(例如,如果您的类持有对文档对象的共享引用),您也只会遇到麻烦。