2013-08-31 108 views
10
Class Shared{  
    public void sharedMethod(Object o){ 
      //does something to Object 
    }  
} 

//this is how threads call the shared method 
run(){ 
    sharedInstance.sharedMethod(someObject); 
} 

现在将o作为参数传递给方法。同一个方法被多个线程并行调用。我们能否安全地说这段代码是线程安全的?Java中的方法参数是否是线程安全的?

有两种情况:

  • 如果someObject被线程之间共享
  • 如果每个线程都有自己的someObject
+0

不,你不能这么说。 – bmargulies

回答

10

没有副本,你可以这么说。方法参数对于线程来说是本地的,也就是说每个线程都有自己的o引用变量的副本,但是如果您使用多个线程中的同一对象调用此方法,那么参数将在它们之间共享(请记住,Java是pass-by -值)。在这种情况下,您需要提供明确的同步以避免麻烦。

+0

您有2个不同的“参考”副本(一个调用方法,一个调用方法 - 因为按值传递),而不是“对象”本身。在一个方法中改变“引用”不会影响另一个方法(例如,调用方法中的'o = null'不会使调用方法中的'o'无效),而是改变它们引用的“对象”(在这种情况下两者都指向同一个对象)对另一个可见。因此,两个线程都在同一个对象上工作,因此不是线程安全的。 – user104309

0

是的,但只有在两种情况下

  • 如果每一个对象,你通过在o参数不变
  • 如果你的代码,保证了至多有一个线程工作该对象由o引用。

否则 - 没有,由于对象的内部状态可以通过多个线程同时被改变。

1

如果您在多个线程中调用相同的方法,并将其传递给同一个对象,则该对象绝对是而不是的安全。

1

当你创建一个线程时,它将创建自己的堆栈(方法和局部变量)。

两个线程将有两个堆栈,一个线程永远不会与任何其他线程共享堆栈。

只有在您对同一个对象调用它时才会生效。

+1

@Narenda正在谈论对象参数(通过引用传递),所以它不是线程安全的。 – camposer

0

局部变量存储在每个线程自己的堆栈中。这意味着线程之间永远不会共享局部变量。这也意味着所有本地原始变量都是线程安全的。

EDIT

在本例中的LocalObject实例未从该方法返回,也不是传递到来自sharedMethod()方法外访问的任何其他对象。

执行sharedMethod()方法的每个线程都将使用自己的Object o作为参数。

所以,整个方法sharedMethod()似乎是线程安全的。

当然唯一的例外是,如果使用对象o作为参数调用的方法之一,以允许从其他线程访问它的方式存储对象o实例。

0

这样对待它。

如果您的线程不共享任何公共资源,则不可能存在并发问题。 尽管从我们提供的信息中可以看出,唯一可以在此共享的是someObject。如果它本身是线程安全的,或者是针对每个线程进行复制,那么一般情况下您的代码都是线程安全的,除非有其他共享资源。