노트코드
노트코드
노트코드

블로그 메뉴

  • 홈
  • 이력서
  • 이전 블로그
  • 글쓰기
  • 관리자페이지
  • 분류 전체보기 (57)
    • 코틀린 (2)
      • 실무 프로젝트로 배우는 Kotlin & Sprin.. (2)
    • JAVA (1)
      • 디자인패턴 (1)
      • 객체지향 5대원칙 (0)
    • SPRING (32)
      • JPA (11)
      • 스프링시큐리티 (1)
      • 스프링 (8)
      • QueryDsl (1)
      • 스프링배치 (11)
    • AZURE (0)
    • ETC (10)
      • MAVEN (0)
      • GIT (0)
      • ReMind (3)
      • Exception (1)
      • CS (6)
    • 책 (8)
      • 이것이 자바다 (8)

최근 글

최근 댓글

태그

  • 스프링
  • JPA
전체 방문자
오늘
어제
hELLO · Designed By 정상우.
노트코드

노트코드

SPRING/스프링

[스프링 핵심 원리-고급] ThreadLocal

2022. 1. 21. 01:06

쓰레드 로컬은 해당 쓰레드만 접근할 수 있는 특별한 저장소를 말한다.

(같은 인스턴스의 쓰레드 로컬 필드에 접근해도 문제가 없음)

  • ThreadLocal을 활용한 예제 코드 작성
@Slf4j
public class ThreadLocalService {

    private ThreadLocal<String> nameStore = new ThreadLocal<>();

    public String logic(String name) {
        log.info("저장 name={} -> nameStore={}", name, nameStore.get());
        nameStore.set(name);

        sleep(1000);
        log.info("조회 nameStore={}", nameStore.get());
        return nameStore.get();
    }

    private void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();

        }

    }
}
  • 동시성 문제가 발생하지 않는 코드 작성
@Slf4j
public class ThreadLocalServiceTest {

    private ThreadLocalService fieldService = new ThreadLocalService();

    @Test
    void field() {
        log.info("main start");
        Runnable userA = () -> fieldService.logic("userA");
        Runnable userB = () -> fieldService.logic("userB");

        Thread threadA = new Thread(userA);
        threadA.setName("thread-A");

        Thread threadB = new Thread(userB);
        threadB.setName("thread-B");

        threadA.start();
        sleep(2000);
        threadB.start();
        sleep(3000);
        log.info("main exit");
    }

    private void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

//01:00:39.413 [Test worker] INFO hello.advanced.threadlocal.ThreadLocalServiceTest - main start
//01:00:39.419 [thread-A] INFO hello.advanced.threadlocal.code.ThreadLocalService - 저장 name=userA -> nameStore=null
//01:00:40.439 [thread-A] INFO hello.advanced.threadlocal.code.ThreadLocalService - 조회 nameStore=userA
//01:00:41.424 [thread-B] INFO hello.advanced.threadlocal.code.ThreadLocalService - 저장 name=userB -> nameStore=null
//01:00:42.431 [thread-B] INFO hello.advanced.threadlocal.code.ThreadLocalService - 조회 nameStore=userB
//01:00:44.435 [Test worker] INFO hello.advanced.threadlocal.ThreadLocalServiceTest - main exit
}​

 

 

  1. userA요청이 들어옴 nameStore에 userA저장
  2. userB요청이 들어옴 nameStore에 null인 상태를 볼수 있음(기존 이전글에서는 userA가 저장되어있었음)
  • 동시성 발생하게 코드 작성
@Test
    void field() {
        log.info("main start");
        Runnable userA = () -> fieldService.logic("userA");
        Runnable userB = () -> fieldService.logic("userB");

        Thread threadA = new Thread(userA);
        threadA.setName("thread-A");

        Thread threadB = new Thread(userB);
        threadB.setName("thread-B");

        threadA.start();
        sleep(100);
        threadB.start();
        sleep(3000);
        log.info("main exit");
        
//01:03:57.595 [thread-A] INFO hello.advanced.threadlocal.code.ThreadLocalService - 저장 name=userA -> nameStore=null
//01:03:57.711 [thread-B] INFO hello.advanced.threadlocal.code.ThreadLocalService - 저장 name=userB -> nameStore=null
//01:03:58.616 [thread-A] INFO hello.advanced.threadlocal.code.ThreadLocalService - 조회 nameStore=userA
//01:03:58.722 [thread-B] INFO hello.advanced.threadlocal.code.ThreadLocalService - 조회 nameStore=userB
    }
  1. userA요청이 들어오고 nameStore에 userA저장중
  2. userA요청이 끝나기전에 userB요청이 들어왔지만, ThreadLocal로 인해 서로의 값에 영향을 주지 않음

 

 

'SPRING > 스프링' 카테고리의 다른 글

[스프링 핵심 원리-고급] 템플릿 콜백 패턴  (0) 2022.01.27
[스프링 핵심 원리 -고급] 전략패턴  (0) 2022.01.27
[스프링 핵심 원리-고급] 템플릿 메서드 패턴  (0) 2022.01.25
[스프링 핵심 원리-고급] 쓰레드 로컬 주의사항  (0) 2022.01.22
[스프링 핵심 원리-고급]필드 동기화 -동시성 문제  (0) 2022.01.21
    'SPRING/스프링' 카테고리의 다른 글
    • [스프링 핵심 원리 -고급] 전략패턴
    • [스프링 핵심 원리-고급] 템플릿 메서드 패턴
    • [스프링 핵심 원리-고급] 쓰레드 로컬 주의사항
    • [스프링 핵심 원리-고급]필드 동기화 -동시성 문제
    노트코드
    노트코드
    노션 블로그에서 티스토리로 이전공사중

    티스토리툴바