programing tip

Java에서 지역 변수가 스레드로부터 안전한 이유

itbloger 2020. 9. 19. 10:12
반응형

Java에서 지역 변수가 스레드로부터 안전한 이유


나는 자바에서 멀티 스레딩을 읽고 있었고 이것을 발견했습니다.

지역 변수는 Java에서 스레드로부터 안전합니다.

그 이후로 나는 어떻게 / 왜 지역 변수가 스레드로부터 안전하다고 생각하고 있습니다.

누군가 저에게 알려주십시오.


스레드를 생성하면 자체 스택이 생성됩니다. 두 개의 스레드에는 두 개의 스택이 있으며 하나의 스레드는 다른 스레드와 스택을 공유하지 않습니다.

프로그램에 정의 된 모든 지역 변수는 스택에 메모리가 할당됩니다 (Jatin이 언급했듯이 여기서 메모리는 객체에 대한 참조 값 및 기본 유형에 대한 값을 의미합니다) (스레드에 의한 각 메서드 호출은 자체 스택에 스택 프레임을 생성합니다). 이 스레드에 의해 메소드 실행이 완료되면 스택 프레임이 제거됩니다.

이 개념을 이해하는 데 도움이 될 수 있는 YouTube의 스탠포드 교수의 훌륭한 강의가 있습니다.


지역 변수는 각 스레드의 자체 스택에 저장됩니다. 즉, 로컬 변수는 스레드간에 공유되지 않습니다. 이는 또한 모든 로컬 기본 변수가 스레드로부터 안전함을 의미합니다.

public void someMethod(){

   long threadSafeInt = 0;

   threadSafeInt++;
}

객체에 대한 로컬 참조는 약간 다릅니다. 참조 자체는 공유되지 않습니다. 그러나 참조 된 객체는 각 스레드의 로컬 스택에 저장되지 않습니다. 모든 개체는 공유 힙에 저장됩니다. 로컬에서 생성 된 객체가 생성 된 메서드를 이스케이프하지 않는 경우 스레드로부터 안전합니다. 실제로 이러한 메서드 나 개체 중 어느 것도 다른 스레드에서 전달 된 개체를 사용할 수없는 한 다른 메서드 및 개체에 전달할 수도 있습니다.


기능 정의와 같은 방법을 생각하십시오. 두 스레드가 동일한 메서드를 실행하면 전혀 관련이 없습니다. 그들은 각각 각 지역 변수의 고유 한 버전을 만들고 어떤 식 으로든 서로 상호 작용할 수 없습니다.

변수가 로컬이 아닌 경우 (예 : 클래스 수준에서 메서드 외부에 정의 된 인스턴스 변수), 메서드의 단일 실행이 아닌 인스턴스에 연결됩니다. 이 경우 동일한 메서드를 실행하는 두 개의 스레드는 둘 다 하나의 변수를 볼 수 있으며 스레드로부터 안전하지 않습니다.

다음 두 가지 경우를 고려하십시오.

public class NotThreadsafe {
    int x = 0;
    public int incrementX() {
        x++;
        return x;
    }
}

public class Threadsafe {
    public int getTwoTimesTwo() {
        int x = 1;
        x++;
        return x*x;
    }
}

첫 번째에서 동일한 인스턴스에서 실행되는 두 개의 스레드 NotThreadsafe는 동일한 x를 보게됩니다. 스레드가 x를 변경하려고하기 때문에 위험 할 수 있습니다! 두 번째로 동일한 인스턴스에서 실행되는 두 개의 스레드 Threadsafe는 완전히 다른 변수를 보게되며 서로 영향을 미칠 수 없습니다.


Nambari와 같은 다른 답변 외에도.

귀찮은 유형 메서드에서 지역 변수를 사용할 수 있음을 지적하고 싶습니다.

이 메서드는 스레드 안전성을 손상시킬 수있는 다른 스레드에서 호출 될 수 있으므로 Java는 성가신 유형에 사용되는 모든 지역 변수를 최종적으로 선언하도록 강제합니다.

다음 불법 코드를 고려하십시오.

public void nonCompilableMethod() {
    int i=0;
    for(int t=0; t<100; t++)
    {
      new Thread(new Runnable() {
                    public void run() {
                      i++; //compile error, i must be final:
                      //Cannot refer to a non-final variable i inside an
                      //inner class defined in a different method
                    }
       }).start();
     }
  }

If java did allow this (like C# does through "closures"), a local variable would no longer be threadsafe in all circumstances. In this case, the value of i at the end of all the threads is not guaranteed to be 100.


Each method invocation has its own local variables and, obviously, a method invocation happens in a single thread. A variable that is only updated by a single thread is inherently thread-safe.

However, keep a close eye on what exactly is meant by this: only the writes to the variable itself are thread-safe; calling methods on the object that it refers to is not inherently thread-safe. Same goes for directly updating object's variables.


Thread will have its own stack. Two threads will have two stacks and one thread never shares its stack with other thread. Local variables are stored in each thread's own stack. That means that local variables are never shared between threads.


Basically Four Type Of Storage Are There in java to store Class Information and data:

Method Area,Heap,JAVA Stack,PC

so Method area and Heap is shared by all the threads but every thread is having its own JAVA Stack and PC and that is not shared by any other Threads.

Each method in java is as Stack frame. so, when one method is called by a thread that stack frame is loaded on its JAVA Stack.All the local variable which are there in that stack frame and related operand stack are not shared by others. PC will have information of next instruction to execute in method's byte code. so all the local variables are THREAD SAFE.

@Weston has also Given good answer.


I like the jenkov's explanation

The thread stack contains all local variables for each method being executed (all methods on the call stack). A thread can only access it's own thread stack. Local variables created by a thread are invisible to all other threads than the thread who created it. Even if two threads are executing the exact same code, the two threads will still create the local variables of that code in each their own thread stack. Thus, each thread has its own version of each local variable.

All local variables of primitive types ( boolean, byte, short, char, int, long, float, double) are fully stored on the thread stack and are thus not visible to other threads. One thread may pass a copy of a pritimive variable to another thread, but it cannot share the primitive local variable itself.

The heap contains all objects created in your Java application, regardless of what thread created the object. This includes the object versions of the primitive types (e.g. Byte, Integer, Long etc.). It does not matter if an object was created and assigned to a local variable, or created as a member variable of another object, the object is still stored on the heap.

enter image description here A local variable may be of a primitive type, in which case it is totally kept on the thread stack.

A local variable may also be a reference to an object. In that case the reference (the local variable) is stored on the thread stack, but the object itself if stored on the heap.

Please read more - http://tutorials.jenkov.com/java-concurrency/java-memory-model.html

참고URL : https://stackoverflow.com/questions/12825847/why-are-local-variables-thread-safe-in-java

반응형