Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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_Multithreading_Static Methods - Fatal编程技术网

Java 如果两个线程有自己的对象访问相同的对象,静态方法是否会产生不好的结果?

Java 如果两个线程有自己的对象访问相同的对象,静态方法是否会产生不好的结果?,java,multithreading,static-methods,Java,Multithreading,Static Methods,如果两个线程访问同一个线程,静态非同步方法是否会产生不好的结果 public class MySubjectUtils { public static MyResponseClass createMyResponseClass(MyParameter record) { if (record == null) { return null; } MyResponseClass mRes = new MyResponseClass() mRes.setName

如果两个线程访问同一个线程,静态非同步方法是否会产生不好的结果

public class MySubjectUtils {
   public static MyResponseClass createMyResponseClass(MyParameter record) {
   if (record == null) {
     return null;
   }
   MyResponseClass mRes = new MyResponseClass()
   mRes.setName(record.getName());
   mRes.setAddress(record.getAddress());   
   return mRes;
}

如果两个或多个线程试图访问MySubjectUtils.createMyResponseClassrecord;两个线程都会给出自己的结果,还是会把结果混在一起?

不会有任何性能问题,而且由于该方法没有访问某些共享资源,线程将得到自己独特的结果

由于MySubjectUtils.createMyResponseClassrecord方法创建MyResponseClass的新实例,因此对该方法的每次调用都将创建一个新对象。因此,每个线程将接收自己的对象。 如果两个线程都传递相同的记录对象,那么它们的MyResponseClass实例的实际内容将是相同的。 如果线程正在传递记录对象的不同实例,那么它们的MyResponseClass实例将具有不同的内容。
同步化不会影响代码,它会影响数据

当您在一个方法上看到synchronized关键字时,您可能会认为它锁定了该方法本身,但事实并非如此;它会锁定被调用对象的实例、this对象,或者,对于静态方法,它会锁定被调用对象的类。换句话说,它控制类的任何静态成员变量

因此,synchronized关键字仅在静态方法访问静态变量时才有用

我看不到您的方法访问任何静态变量,因此synchronized关键字在其上是完全不必要的。

如果对象记录引用的是不可变的,您不需要在该方法中进行任何同步,因为这是该方法引用的唯一潜在共享资源。其他一切都是本地的方法

但是,如果引用的对象记录不是不可变的,并且可以跨线程使用,则该方法调用getName和getAddress之间的另一个线程可能会修改它,从而导致无效响应


因此,答案是:您可能需要也可能不需要同步,如果需要,实现方式将有所不同。在这两种情况下,它都取决于MyParameter类的定义以及调用代码如何使用对象结果引用。

您无法从该代码中分辨出可能的重复。如果两个线程使用相同的记录对象,则这取决于记录中数据的写入方式是否与两个线程正确同步。如果是这样,并且你的getter只读取数据,那么你就没事了。他们很可能正在访问一个共享资源:record,参数引用的对象。这是真的,但与本例无关。MyResponseClass对象对于不同的线程仍然是唯一的,因为字符串在Java中是不可变的,如果记录发生更改,名称和地址将不会更改。这与是否需要同步有关:如果没有同步,则可以在调用getName和getAddress之间更改所引用的对象记录,使结果不正确。除非该对象是不可变的,否则问题不会说,如果多线程访问该方法,则需要同步。除非引用的对象记录是不可变的,否则需要同步以防止响应无效,例如。,引用的对象记录可以在方法调用getName和getAddress之间进行修改。@T.J.Crowder我将问题中两个拥有自己对象的线程部分解释为暗示每个记录都位于自己的线程内。在任何情况下,如果在多线程环境中传递可变记录,那么问题在于记录的使用方式,而不是方法本身。使方法原子化可能是OP最不关心的问题,而静态同步是实现原子性的一种极为低效的方式。@T.J.Crowder Naiver的一个反复出现的问题,所以问题是,我必须要么坚持被问的内容的无意义的狭窄范围,或者面临着一项艰巨的任务,那就是必须写一篇关于代码中可能发生的所有事情的论文,而OP没有展示,也没有询问这些事情。请看,这是一个web服务,它进一步调用web服务,我们从这个进一步的服务响应中创建新的响应。现在,一个web服务被多个用户点击,参数被发送到进一步的服务,对于每个用户,我们都会得到单独的响应,需要填充到MyResponseClass中。为此,我使用STATICMETHOD.methodname,因为我希望所有实用工具方法都在一个位置。@fatherazrael:如果您知道调用代码是唯一引用了该结果对象和调用代码不与其他线程共享该对象,您不需要同步。例如:如果结果是调用代码中的本地结果,并且没有与其他线程共享该结果的方法一起使用,则可以 h进一步调用一个web服务,并从该进一步的服务响应中创建新的响应。现在,一个web服务被多个用户点击,参数被发送到进一步的服务,对于每个用户,我们得到单独的响应,需要填充到MyResponseObject中,为此,我使用STATICMETHOD.methodname,因为我希望所有实用工具方法都在一个位置。