>Java >java지도 시간 >ThreadLocal 원리에 대한 간략한 분석

ThreadLocal 원리에 대한 간략한 분석

(*-*)浩
(*-*)浩앞으로
2019-09-29 16:18:302733검색

ThreadLocal은 스레드 지역 변수를 의미합니다! 그렇다면 스레드 지역 변수는 무엇입니까? 이게 무슨 소용이 있나요? 면접에서 질문을 받았는데 아무 말도 못 했다는 건가요? 오늘은 이 제품의 소스코드를 살펴보고 그것이 무엇을 하는지 근본적으로 이해해 보도록 하겠습니다.

ThreadLocal 원리에 대한 간략한 분석

Thread, ThreadLocalMap 및 Entry의 관계

사실 소스 코드 구현을 연구해 본 결과 실제로는 생각만큼 복잡하지 않습니다.

1. Java는 통과할 수 있습니다. Thread.currentThread()를 사용하여 현재 Thread 인스턴스 객체를 얻습니다. 이제 Thread 객체 인스턴스를 얻을 수 있으므로 Thread 객체에 대한 값 설정과 같은 인스턴스(속성)를 조작할 수 있습니다.

2. 각 Thread 객체에는 항목 배열이 있는 ThradLocalMap 인스턴스가 있습니다. Value 속성은 ThreadLocal에 대한 약한 참조 속성입니다. ThreadLocal의 핵심 속성:

static class Entry extends WeakReference<ThreadLocal<?>> {
    /** The value associated with this ThreadLocal. */
    Object value;

    Entry(ThreadLocal<?> k, Object v) {
        super(k);
        value = v;
    }
}

Entry는 WeakReference에서 상속되며 해당 키는 ThreadLocal 개체입니다! (그림 1)

ThreadLocal 원리에 대한 간략한 분석

두 가지 지식 포인트 1과 2를 결합하면 Thread 객체를 얻은 후 현재 스레드 객체의 ThreadLocalMap 객체를 제어하고 저장하려는 값을 제공할 수 있음을 알 수 있습니다. ThreadLocalMap에 Entry, Thread, ThreadLocalMap의 value 속성과 value 사이의 관계는 다음 그림(그림 2)으로 나타낼 수 있습니다.

ThreadLocal 원리에 대한 간략한 분석

위 그림을 통해 결론을 내릴 수 있습니다. Thread 개체는 ThreadLocalMap을 보유합니다. object 이면 ThreadLoalMap 개체에는 여러 ThreadLlocal 개체와 ThreadLocal 개체가 위치한 스레드의 값이 포함됩니다! ! ! 간단히 말해서: Thread 객체는 여러 ThreadLocal 객체의 변수 값을 보유할 수 있습니다

그렇다면 ThreadLocal과 Thread 사이의 관계는 무엇입니까? 두 사람은 어떻게 값을 읽을 수 있습니까? 아래는 소스코드를 기반으로 한 간략한 분석입니다.

ThreadLocal과 Thread의 관계

ThreadLocal의 set 메소드를 먼저 살펴보세요.

 public void set(T value) {
         //获取当前线程
        Thread t = Thread.currentThread();
        //获取当前线程持有的ThreadLocalMap
        ThreadLocal.ThreadLocalMap map = getMap(t);
        //将value设置给threadlocalMap
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

set 메소드는 매우 논리적이고 간단합니다(j는 위의 그림 2와 결합하면 더 잘 이해할 수 있습니다).

1. currentThread 메서드 Thread 객체를 통해 전류를 가져옵니다.

2. 현재 Thread 객체의 ThreadLoalMap 객체를 가져옵니다.

3. 값과 ThreadLocal 객체 자체를 결합하여 Entry 객체를 형성하고

의 Entry 유형 배열에 저장합니다. ThreadLoalMap.

ThreadLocal의 get 메소드를 살펴보겠습니다.

public T get() {
    //获取当前线程
    Thread t = Thread.currentThread();
    //获取当前线程的ThreadLocalMap对象
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        //获取与ThreadLocal对象想关联的value
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings("unchecked")
            //获取值
            T result = (T)e.value;
            return result;
        }
    }
    //为空返回初始化值
    return setInitialValue();
}

get의 전체 논리는 개발될 수 있으며 또한 매우 간단합니다.

1 현재 Thread 객체를 가져옵니다

2. 현재 Thread 객체의 객체

3. 특히 ThreadLocal을 키로 사용하여 ThreadLocalMap에서 ThreadLocal과 연관된 Entry 객체를 얻습니다.

4. 3단계에서 항목의 값 속성을 가져와 반환합니다.

get 및 set 메소드를 전체적으로 관찰하면 다음과 같은 결론을 내릴 수 있습니다. ThreadLocal 객체가 set 메소드를 호출하면 ThreadLocal 객체가 get 메소드를 호출할 때 Thread 객체의 ThreadLocalMap에 값이 추가됩니다. Thread 개체의 ThreadLocalMap에서 값을 가져옵니다. 핵심은 Thread 객체의 ThreadLocalMap 객체를 조작하여 값을 읽고 쓰는 것입니다. 원리는 간단합니다.

그렇다면 서로 다른 스레드에 위치한 서로 다른 ThreadLocal 객체와 다른 스레드에 값을 저장하는 것 사이에는 어떤 관계가 있을까요? 다음 그림을 통해 명확하게 설명할 수 있습니다.

ThreadLocal 원리에 대한 간략한 분석

ThreadLocal의 사용 예

Android에서는 스레드당 하나의 Looper 개체만 있다는 것을 알고 있는데 어떻게 수행합니까? 역할을 하는 것은 ThreadLocal입니다. Looper의 prepare 메소드를 살펴보세요.

//定义一个静态的ThreadLocal变量
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); 

private static void prepare(boolean quitAllowed) {
        //一个Thread只能关联一个Looper对象
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

prepare 메소드를 관찰하면 먼저 sThreadLocal의 get 메소드를 사용하여 현재 스레드에 이미 Looper 객체가 있는지 확인하는 것을 알 수 있습니다. , 현재 스레드가 설정되지 않은 경우 예외가 발생합니다. Looper 개체가 설정되지 않은 경우 ThreadLocal의 set 메서드를 호출하여 Looper 개체를 초기화하고 이를 현재 스레드에 전달합니다.

sThreadLocal.set(new Looper(quitAllowed));

이렇게 하면 스레드에 하나만 있음이 보장됩니다. 루퍼 개체.

지금까지는 ThreadLocal의 원리를 기본적으로 분석했으며 내부적으로 어떻게 설정하고 가져오는지는 필요하지 않기 때문에 ThreadLocal의 작동 이유와 사용 시나리오만 이해하면 됩니다.

위 내용은 ThreadLocal 원리에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제