在局部变量上同步是否合理?

新手上路,请多包涵

从Java内存模型我们知道,每个线程都有自己的线程栈,局部变量放在每个线程自己的线程栈中。

并且 其他 线程无法访问这些局部变量。

那么在什么情况下我们应该同步局部变量呢?

原文由 NingLee 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

您正在谈论以下情况:

 public class MyClass {
    public void myMethod() {
        //Assume Customer is a Class
        Customer customer = getMyCustomer();
        synchronized(customer) {
            //only one thread at a time can access customer object
              which ever holds the lock
        }
    }
}

在上面的代码中, customer 是一个局部引用变量,但你仍然使用同步块 来限制对对象的访问 customer 指向( 一次由一个线程).

在 Java 内存模型中, 对象存在于堆中(即使引用对于存在于堆栈中的线程而言是本地的),而同步就是限制一次仅由一个线程访问堆上的对象

简而言之, 当您说局部变量(非原始变量)时,只有引用是局部的,而不是实际对象本身,即它实际上指的是堆上的一个对象,可以被许多其他线程访问。因此,您需要对对象进行同步,以便单个线程一次只能访问该对象。

原文由 developer 发布,翻译遵循 CC BY-SA 4.0 许可协议

有两种情况:

  1. 局部变量是原始类型,如 intdouble
  2. 局部变量是引用类型,如 ArrayList

在第一种情况下,您 无法 同步,因为您只能在对象(由引用类型变量指向)上进行同步。

在第二种情况下,这完全取决于局部变量指向什么。如果它指向其他线程(也可以)也指向的对象,那么您需要确保您的代码已正确同步。

示例:您从 static 或实例字段分配局部变量,或者您从共享集合中获取对象。

但是,如果该对象是在您的线程中创建的并且仅分配给该局部变量,并且您从不从您的线程向另一个线程提供对它的引用,并且对象实现本身也没有提供引用,那么您不需要担心同步。

原文由 Erwin Bolwidt 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏