仅使用局部变量而不使用实例变量就足够了。因此只使用堆栈上的内存(每个线程)。
但是当你创建一个方法本地的新MyObject时会发生什么。是否在堆上创建了新对象?它是线程安全的,因为它的引用是本地的(线程安全的)?
答案 0 :(得分:5)
它是线程安全的,因为如果它仅由该特定方法中的变量引用(正如您所说的那样,是一个局部变量),那么没有其他线程可能具有对该对象的引用,因此无法更改它
想象一下你和我是海盗(线程)。你去把你的战利品(对象)埋在岛上(堆),保留一张地图(参考)。我碰巧使用同一个岛来掩埋我的战利品,但除非你把你的地图给我,否则我会在整个岛上挖掘(Java岛上不允许),我不能乱用你的藏匿处。
答案 1 :(得分:4)
您的新MyObject
是线程安全的,因为每次调用该方法都会在堆上创建自己的本地实例。没有一个电话是指一种常见的方法;如果有N个调用,则表示堆上有MyObject
个N个实例。当方法退出时,只要您不将其返回给调用者,每个实例都有资格使用GC。
答案 2 :(得分:3)
好吧,我问你一个问题:将方法限制为局部变量是否意味着你的方法无法与另一个线程共享资源?如果没有,那么显然这对于线程安全来说是不够的。
如果您担心另一个线程是否可以修改您在另一个线程中创建的对象,那么您唯一需要担心的是永远不会从该线程中泄漏对该对象的引用。如果你实现了这个目标,那么你的对象将在堆中,但没有其他线程可以引用它,因此无关紧要。
关于我的第一个陈述,这里是一个没有实例变量的方法:
public void methodA() {
File f = new File("/tmp/file");
//...
}
这并不意味着两个线程之间不能存在共享资源: - )。
答案 3 :(得分:0)
Threre无法通过其他线程访问此类对象引用。但是如果该对象不是线程安全的,那么整体线程安全性就会受到影响。
例如,考虑MyObject是HashMap。
如果它在堆中,它不是线程安全的,则无效。堆不能通过指针算法访问,因此它不会影响对象的实际存储位置(除ThreadLocal之外)。