15
Class Shared{    
     public void sharedMethod(Object o){
          //does something to Object
     }     
}

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

现在o作为参数传递给方法。多个线程并行调用相同的方法。我们可以肯定地说这段代码是线程安全的吗?

有两种情况:

  • 如果someObject在线程之间共享
  • 如果每个线程都有自己的副本someObject
4

6 回答 6

16

不,你不能这么说。方法参数是线程本地的,这意味着每个人都有自己的o引用变量副本,但是如果您从多个线程中使用同一个对象调用此方法,则参数将在它们之间共享(请记住,Java 是传递-价值)。在这种情况下,您需要提供显式同步以避免麻烦。

于 2013-08-31T11:30:52.500 回答
3

是的,但仅在两种情况下

  • 如果您传入o参数的每个对象都是不可变的,
  • 如果您的代码保证最多有一个线程在处理o.

否则 -,因为对象的内部状态可以由多个线程同时更改。

于 2013-08-31T11:33:10.040 回答
2

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

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

直到你在同一个对象上调用它才会生效。

于 2013-08-31T11:38:05.953 回答
1

如果您在多个线程中调用相同的方法,并传递相同的对象,那么该对象绝对不安全

于 2013-08-31T11:33:31.383 回答
0

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

编辑

此示例中的 LocalObject 实例不会从方法返回,也不会传递给可从sharedMethod()方法外部访问的任何其他对象。

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

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

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

于 2013-08-31T11:49:54.207 回答
0

以这种方式对待它。

如果您的线程不共享任何公共资源,那么就不可能出现并发问题。从您提供的信息中我们可以看出,这里唯一可以共享的是someObject. 如果它本身是线程安全的,或者为每个线程复制,那么您的代码通常是线程安全的,除非有其他共享资源。

于 2013-08-31T12:07:06.217 回答