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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43134998/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 07:07:34  来源:igfitidea点击:

Is reasonable to synchronized on local variable?

javamultithreadingsynchronizationlocal-variables

提问by NingLee

From the java memory model, we know every thread has his own thread stack, and that local variables are placed in each thread's own thread stack.

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

And that otherthreads can't access these local variables.

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

So in which case, we should synchronized on local variables?

那么在哪种情况下,我们应该对局部变量进行同步?

回答by developer

You are talking about the below case:

您正在谈论以下案例:

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
        }
    }
}

In the above code, customeris a local reference variable, but you are still using a synchronized blockto restrict access to the object customeris pointing to (by a single thread at a time).

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

In Java memory model, objects live in heap (even though references are local to a Thread which live in a stack) and synchronization is all about restricting access to an object on the heapby exactly one thread at a time.

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

In short, when you say local variable (non-primitive), only reference is local, but not the actual object itself i.e., it is actually referring to an object on the heapwhich can be accessed by many other threads. Because of this, you need synchronization on the object so that single thread can only access that object at a time.

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

回答by Erwin Bolwidt

There are two situations:

有两种情况:

  1. The local variable is of a primitive type like intor double.
  2. The local variable is of a reference type like ArrayList.
  1. 局部变量是原始类型,如intor double
  2. 局部变量属于引用类型,如ArrayList.

In the first situation, you can'tsynchronize, as you can only synchronize on Objects (which are pointed to by reference-type variables).

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

In the second situation, it all depends on what the local variable points to. If it points to an object that other threads (can) also point to, then you need to make sure that your code is properly synchronized.

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

Examples: you assigned the local variable from a staticor instance field, or you got the object from a shared collection.

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

If, however, the object was created in your thread and only assigned to that local variable, and you never give out a reference to it from your thread to another thread, and the objects implementation itself also doesn't give out references, then you don't need to worry about synchronization.

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

回答by GhostCat

The point is: synchronization is done for a purpose. You use it to ensure that exactlyone thread can do some special protection-worthy activity at any given time.

关键是:同步是有目的的。您可以使用它来确保在任何给定时间只有一个线程可以执行一些特殊的值得保护的活动。

Thus: if you need synchronization, it is always about morethan one thread. And of course, then you need to lock on something that allthose threads have access to.

因此:如果您需要同步,它总是关于多个线程。当然,然后您需要锁定所有这些线程都可以访问的内容。

Or in other words: there is no point in youlocking the door in order to prevent yourselffrom entering the building.

或者换句话说:有中没有点,你把门锁上,以防止自己进入建筑物。

But, as the other answer points out: it actually depends on the definition of "local" variable. Lets say you have:

但是,正如另一个答案所指出的:它实际上取决于“局部”变量的定义。假设你有:

void foo() {
  final Object lock = new Object();
  Thread a = new Thread() { uses lock
  Thread b = new Thread() { uses lock

then sure, that "local" variable can be used as lock for those two threads. And beyond that: that example works because synchronization happens on the monitorof a specific object. And objects reside on the heap. All of them.

那么可以肯定,“本地”变量可以用作这两个线程的锁。除此之外:该示例有效,因为同步发生在特定对象的监视器上。对象驻留在堆上。他们都是。

回答by Boris Pavlovi?

Yes, it does make sense when the local variable is used to synchronize access to a block of code from threads that are defined and created in the same method as the local variable.

是的,当局部变量用于同步从与局部变量相同的方法中定义和创建的线程对代码块的访问时,这确实有意义。