본문 바로가기

강좌/JAVA THREAD

자바 쓰레드(Thread) - 쓰레드로컬(ThreadLocal)

쓰레드 로컬이란걸 정말 몰랐었다.

지금도 잘 모르지만 일단 정의를 보자




ThreadLocal이란?

일반 변수의 수명은 특정 코드 블록(예, 메서드 범위, for 블록 범위 등) 범위 내에서만 유효하다.

{
    int a = 10;
    ...
   // 블록 내에서 a 변수 사용 가능
}
// 변수 a는 위 코드 블록이 끝나면 더 이상 유효하지 않다. (즉, 수명을 다한다.)

반면에 ThreadLocal을 이용하면 쓰레드 영역에 변수를 설정할 수 있기 때문에, 특정 쓰레드가 실행하는 모든 코드에서 그 쓰레드에 설정된 변수 값을 사용할 수 있게 된다. 아래 그림은 쓰레드 로컬 변수가 어떻게 동작하는 지를 간단하게 보여주고 있다.
(출처 : 자바캔)

이라고 되어 있다. 아래 설명도 보자


ThreadLocal의 기본 사용법

ThreadLocal의 사용방법은 너무 쉽다. 단지 다음의 네 가지만 해 주면 된다.
  1. ThreadLocal 객체를 생성한다.
  2. ThreadLocal.set() 메서드를 이용해서 현재 쓰레드의 로컬 변수에 값을 저장한다.
  3. ThreadLocal.get() 메서드를 이용해서 현재 쓰레드의 로컬 변수 값을 읽어온다.
  4. ThreadLocal.remove() 메서드를 이용해서 현재 쓰레드의 로컬 변수 값을 삭제한다.


아래는 쓰레드로컬을 사용한 예제이다.

import java.util.Random;

public class ThreadLocalTest {
    static int counter = 0;
    
    private static class ThreadLocalObject extends ThreadLocal{
        Random random = new Random();
protected Object initialValue(){
    return new Integer(random.nextInt(1000));
    }
    }
    static ThreadLocal tLocal = new ThreadLocalObject();
    private static void displayValues(){
        System.out.println("Thread Name : " + Thread.currentThread().getName() + ", initialValue : " + tLocal.get() 
+ ", counter : " + counter);
    }
    public static void main(String[] args) {
        displayValues();
Runnable runner = new Runnable(){
    public void run(){
        synchronized(ThreadLocalTest.class){
    counter++;
}
   
displayValues();
   
try {
    Thread.sleep( ((Integer)tLocal.get()).intValue());
    displayValues();
} catch (InterruptedException e) {
    e.printStackTrace();
}
            }
};
for(int i=0;i<3;i++){
    Thread t = new Thread(runner);
    t.start();
}
    }
}

결과


결과를 보면 쓰레드가 수차례 반복이 되었지만 해당 쓰레드에 대한 initialValue값은 변하지 않았다.

Thread-1의 초기값이 661인데 counter가 증가 했음에도 불구하고 나중에 봐도 661이다.



음..그래도 머리속에는 잘 안들어 온다..반복하는 수밖에 없다.