ThreadLocal 면접 문제 에 대해 서 정말 알 겠 어 요?

설명 하 다.
면접 관:ThreadLocal 에 대한 이 해 를 말씀 해 주세요.
그럼 어떻게 대답 해 야 되 지???당신 도 생각해 보 세 요.다음은 0 도의 사 고 를 보 세 요.
  • ThreadLocal 은 어디 에 쓰 입 니까?
  • ThreadLocal 디 테 일!
  • ThreadLocal 의 최고의 실천!
  • 사고
  • ThreadLocal 은 어디 에 쓰 입 니까?
    ThreadLocal 이 어디 에 사용 되 는 지 토론 하기 전에 하나의 스 레 드 만 있 으 면 ThreadLocal 은 말 할 필요 가 없습니다.ThreadLocal 은 다 중 스 레 드 장면 에 사 용 됩 니 다!!
    ThreadLocal 은 두 가지 용도 로 요약 합 니 다.
  • 스 레 드 컨 텍스트 정 보 를 저장 하고 필요 한 곳 에서 얻 을 수 있 습 니 다!!
  • 스 레 드 가 안전 하고 특정한 상황 에서 스 레 드 안전 이 동기 화 되 어야 하 는 성능 손실 을 고려 해 야 합 니 다!!
  • 스 레 드 컨 텍스트 정 보 를 저장 하고 필요 한 곳 에서 얻 을 수 있 습 니 다!!
    ThreadLocal 의 특성 상 같은 스 레 드 를 어 딘 가 에 설정 하면 그 다음 에 임의의 곳 에서 얻 을 수 있 습 니 다.스 레 드 컨 텍스트 정 보 를 저장 할 수 있 습 니 다.
    모든 요청 이 어떻게 후속 으로 연결 되 는 지,ThreadLocal 로 set 를 진행 할 수 있 습 니 다.다음 에 로 그 를 기록 해 야 하 는 방법 에서 get 을 요청 id 로 가 져 와 서 전체 요청 을 연결 할 수 있 습 니 다.
    또한 Spring 의 사무 관 리 는 ThreadLocal 로 Connection 을 저장 하여 각 DAO 가 같은 Connection 을 가 져 올 수 있 고 트 랜 잭 션 스크롤,제출 등 을 할 수 있 습 니 다.
    비고:ThreadLocal 의 이러한 용 도 는 우수한 프레임 안에 사 용 될 때 가 많 습 니 다.보통 우 리 는 접촉 이 적 고 오히려 아래 의 장면 은 우리 가 더 많이 접 합 니 다!
    스 레 드 가 안전 합 니 다.어떤 상황 에서 스 레 드 안전 이 동기 화 되 어야 하 는 성능 손실 을 고려 해 야 합 니 다!!
    ThreadLocal 은 다 중 스 레 드 프로그램의 병행 문 제 를 해결 하기 위해 새로운 방향 을 제공 했다.그러나 ThreadLocal 에 도 한계 가 있 습 니 다.아 리 규범 을 살 펴 보 겠 습 니 다.

    모든 스 레 드 가 ThreadLocal 에 데 이 터 를 읽 고 쓰 는 것 은 스 레 드 격 리 이 며 서로 영향 을 주지 않 기 때문에 ThreadLocal 은 공유 대상 의 업데이트 문 제 를 해결 할 수 없습니다!
    정 보 를 공유 할 필요 가 없 기 때문에 경쟁 문제 가 존재 하지 않 습 니 다.그래서 특정한 상황 에서 스 레 드 의 안전 을 확보 하고 특정한 상황 에서 스 레 드 안전 을 고려 해 야 하 는 동기 화 에 따 른 성능 손실 을 피 할 수 있 습 니 다!!
    이런 장면 에서 아 리 규범 에서 도 언급 했다.

    ThreadLocal 디 테 일!
    ThreaLocal 은 예제 코드 를 사용 합 니 다:
    
    public class ThreadLocalTest {
    private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
    public static void main(String[] args) {
    new Thread(() -> {
    try {
    for (int i = 0; i < 100; i++) {
    threadLocal.set(i);
    System.out.println(Thread.currentThread().getName() + "====" + threadLocal.get());
    try {
    Thread.sleep(200);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    } finally {
    threadLocal.remove();
    }
    }, "threadLocal1").start();
    new Thread(() -> {
    try {
    for (int i = 0; i < 100; i++) {
    System.out.println(Thread.currentThread().getName() + "====" + threadLocal.get());
    try {
    Thread.sleep(200);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    } finally {
    threadLocal.remove();
    }
    }, "threadLocal2").start();
    }
    }
    코드 캡 처:

    코드 실행 결과:

    실행 결과 에서 우 리 는 thread Local 1 의 set 값 이 thread Local 2 에 아무런 영향 을 주지 않 는 것 을 볼 수 있 습 니 다!
    Thread,ThreadLocalMap,ThreadLocal 총람 도


    Thread 클래스 는 속성 변수 threadLocals(유형 은 ThreadLocal.ThreadLocalMap)가 있 습 니 다.즉,모든 스 레 드 는 자신의 ThreadLocalMap 이 있 기 때문에 모든 스 레 드 는 이 ThreadLocal 에서 읽 고 쓰 고 격 리 되 며 서로 영향 을 주지 않 습 니 다.
    하나의 ThreadLocal 은 하나의 Object 대상 만 저장 할 수 있 습 니 다.여러 개의 Object 대상 을 저장 하려 면 여러 개의 ThreadLocal 이 필요 합 니 다!!
    그림:

    위의 몇 개의 그림 을 보면 생각 이 뚜렷 해 질 것 입 니 다.우리 Entry 의 key 는 ThreadLocal 을 가리 키 며 점선 으로 약 한 인용 을 표시 합 니 다.다음은 ThreadLocalMap 을 살 펴 보 겠 습 니 다.

    자바 대상 의 인용 은 강 인용,소프트 인용,약 인용,허 인용 을 포함한다.
    약 한 인용 과 관련 되 기 때문에 간단하게 설명 하 겠 습 니 다.
    약 한 인용 도 불필요 한 대상 을 묘사 하 는 데 쓰 인 다.JVM 이 쓰레기 수 거 를 할 때 메모리 가 충분 하 든 그렇지 않 든 이 대상 은 약 한 인용 과 관련 이 있 을 뿐 회수 된다.
    ThreadLocalMap 의 Entry 키 만 ThreadLocal 을 가리 킬 때 ThreadLocal 은 회수 합 니 다!!
    ThreadLocal 이 쓰레기 에 수 거 된 후 ThreadLocalMap 에 대응 하 는 Entry 의 키 값 은 null 로 변 하지만 Entry 는 강 한 인용 입 니 다.그러면 Entry 에 저 장 된 Object 는 회수 할 방법 이 없 기 때문에 ThreadLocalMap 은 추가 회수 작업 을 했 습 니 다.

    했 지만 메모리 유출 위험 도 있 습 니 다.(저 는 만난 적 이 없습니다.인터넷 에 비슷 한 장면 이 많 기 때문에 뒤의 ThreadLocal 최고의 실천 을 언급 합 니 다!!)
    ThreadLocal 의 최고의 실천!
    ThreadLocal 이 쓰레기 에 수 거 된 후 ThreadLocalMap 에 대응 하 는 Entry 의 키 값 은 null 로 변 하지만 Entry 는 강 한 인용 입 니 다.그러면 Entry 에 저 장 된 Object 는 회수 할 방법 이 없 기 때문에 ThreadLocalMap 은 추가 회수 작업 을 했 습 니 다.

    비고:많은 경우,우 리 는 모두 온라인 정 지 를 사용 하 는 장면 입 니 다.프로그램 이 멈 추 지 않 습 니 다.스 레 드 는 기본적으로 소각 되 지 않 습 니 다!!
    스 레 드 의 수명 주기 가 매우 길 기 때문에 만약 에 우리 가 ThreadLocal 에 매우 큰 Object 대상 을 설정 하면 set,get 등 방법 은 특정한 조건 에서 호출 되 어 추가 청 소 를 하지만 ThreadLocal 이 쓰레기 로 회수 되면 ThreadLocalMap 에 대응 하 는 Entry 의 키 값 은 null 이 되 지만 그 다음 에는 set,get 등 방법 을 조작 하지 않 습 니 다.
    그래서 가장 좋 은 실천 은 우리 가 사용 하지 않 을 때 자발적으로 remove 방법 으로 청 소 를 해 야 한다.

    여기 서 ThreadLocal 을 static 로 정의 하 는 또 다른 장점 은 ThreadLocal 에 강 한 인용 이 있 기 때문에 ThreadLocalMap 에 대응 하 는 Entry 키 가 영원히 존재 합 니 다.reove 를 실행 할 때 정확하게 위치 추적 하고 삭제 할 수 있 습 니 다!!
    가장 좋 은 실천 방법 은 다음 과 같다.
    
    try {
    //       
    } finally {
    threadLocal  .remove();
    }
    사고 하 다.
    면접 을 볼 때 위의 내용 을 모두 말 할 수 있다 면 개인 적 으로 매우 좋 고 완벽 하 게 대답 할 수 있 을 것 입 니 다.하지만 다음 대답 을 할 수 있다 면 더 완벽 하 다.
    ThreadLocal 에 대해 저 는 Netty 소스 코드 를 볼 때 FastThreadLocal,xxxx 의 열 내용 도 알 아 봤 습 니 다.그것 은 바로 업그레이드 입 니 다.

    내 로 컬 에서 테스트 를 진행 하 는데,FastThreadLocal 의 물동량 은 jdkThreadLocal 의 3 배 정도 이다.

    좋은 웹페이지 즐겨찾기