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
副本
不,你不能这么说。方法参数是线程的本地参数,这意味着每个参数都有自己的o
引用变量副本,但是如果你使用来自多个线程的相同对象调用此方法,那么参数将在它们之间共享(请记住,Java是按值传递的(。在这种情况下,您需要提供显式同步以避免麻烦。
是的,但仅在两种情况下:
- 如果在
o
参数中传递的每个对象都是不可变的, - 如果您的代码保证最多有一个线程在处理
o
引用的对象。
否则 - 否,因为对象的内部状态可以由多个线程同时更改。
当你创建一个线程时,它将创建自己的堆栈(方法和局部变量(。
两个线程将有两个堆栈,一个线程永远不会与任何其他线程共享其堆栈。
在你对同一个对象调用它之前,它不会起作用。
如果在多个线程中调用相同的方法,并向其传递相同的对象,则该对象绝对不安全。
这样对待它。
如果您的线程不共享任何公共资源,则不可能出现并发问题。尽管我们可以从您提供的信息中看出很多,但唯一可以在这里共享的是 someObject
.如果代码本身是线程安全的,或者为每个线程复制,则代码通常是线程安全的,除非有其他共享资源。
局部变量存储在每个线程自己的堆栈中。这意味着局部变量永远不会在线程之间共享。这也意味着所有局部原变量都是线程安全的。
编辑
此示例中的 LocalObject 实例不会从该方法返回,也不会传递给可从 sharedMethod()
方法外部访问的任何其他对象。
执行 sharedMethod()
方法的每个线程都将使用自己的对象o
作为参数。
因此,整个方法似乎sharedMethod()
线程安全的。
当然,唯一的例外是,如果使用 Object o
作为参数调用的方法之一,则以允许从其他线程访问 Object 的方式存储 Object o
实例。