0

只使用局部变量而不使用实例变量就足够了吗?因此仅使用堆栈上的内存(每个线程)。

但是当您创建一个新的 MyObject 方法时会发生什么。新对象不是在堆上创建的吗?它是线程安全的,因为对它的引用是本地的(线程安全的)吗?

4

4 回答 4

5

它是线程安全的,因为如果它仅由该特定方法中的变量引用(如您所说,它是一个局部变量),那么其他线程不可能引用该对象,因此无法更改它。

想象一下你和我是海盗(线程)。你去把你的战利品(对象)埋在一个岛(堆)上,并为它保留一张地图(参考)。我碰巧用同一个岛来掩埋我的战利品,但除非你给我你的地图,或者我去全岛挖掘(这在爪哇岛上是不允许的),否则我不能乱动你的藏匿处。

于 2012-04-18T16:54:56.453 回答
4

您的 newMyObject是线程安全的,因为每次调用该方法都会在堆上创建自己的本地实例。没有一个调用引用通用方法;如果有 N 个调用,这意味着MyObject堆上有 N 个实例。当方法退出时,只要您不将其返回给调用者,每个实例都有资格进行 GC。

于 2012-04-18T16:56:08.133 回答
3

好吧,让我问你一个问题:将你的方法限制为局部变量是否意味着你的方法不能与另一个线程共享资源?如果不是,那么显然这对于​​一般的线程安全来说是不够的。

如果您担心另一个线程是否可以修改您在另一个线程中创建的对象,那么您唯一需要担心的就是永远不要将对该对象的引用泄漏到线程之外。如果你实现了这一点,你的对象将在堆中,但没有其他线程能够引用它,所以没关系。

编辑

关于我的第一个陈述,这是一个没有实例变量的方法:

public void methodA() {
    File f = new File("/tmp/file");
    //...
}

这并不意味着两个线程之间不能有共享资源:-)。

于 2012-04-18T16:56:38.320 回答
0

其他线程无法访问此类对象引用。但是,如果该对象不是线程安全的,那么整个线程安全性就会受到影响。

例如,考虑 MyObject 是一个 HashMap。

如果它在堆中,它不是线程安全的,这个论点是无效的。堆不能通过指针算术访问,因此它不会影响对象的实际存储位置(除了 ThreadLocal 的)。

于 2012-04-18T17:01:31.170 回答