繁体   English   中英

确保Java方法是线程安全的

[英]to ensure a java method is thread safe

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

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

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

想象你和我是海盗(线程)。 您去将赃物(对象)埋在岛(堆)上,并保留一张地图(参考)。 我碰巧用同一个岛埋藏我的战利品,但是除非您给我您的地图,否则我将在整个岛上进行挖掘(在Java岛上是不允许的),所以我不会弄乱您的藏身之处。

您的新MyObject是线程安全的,因为对方法的每次调用都会在堆上创建自己的本地实例。 没有一个调用引用一个通用方法。 如果有N个调用,则表示堆上有N个MyObject实例。 方法退出后,只要您不将其返回给调用方,每个实例都可以使用GC。

好吧,让我问一个问题:将方法限制为局部变量是否意味着您的方法无法与另一个线程共享资源? 如果不是这样,那么显然这通常不足以保证线程安全。

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

编辑

关于我的第一条语句,这是一个没有实例变量的方法:

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

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

Threre无法访问其他线程来访问此类对象引用。 但是,如果该对象不是线程安全的,则将损害总体线程安全。

例如,考虑MyObject是HashMap。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM