본문 바로가기
CS/Java

Thread

by clearinging 2022. 1. 1.
반응형

1. Thread

정의

  • CPU의 코어를 최대한 사용해서 많은 업무를 동시에 처리할 수 있게 도와 주는 것이다

특징

  • 생성 관정에서 조금의 시간이 소요가 된다.
  • 쓰래드 생성에 필요한 메모리 공간이 필요(stack 영역)
  • thread 개수 제한을 두지 않기 때문에 너무 많은 thread를 생성하면 메모리 고갈과 같은 이슈가 발생할 수 있습니다

Thread 생성 방식(Task 등록)

  • Runnable/Callable interface를 상속받은 객체를 실행하는 방식
    • 관리의 편의 성을 더해주기위해서 Java 5부터 Thread pool을 사용 합니다
  • 현재 대부분 Thread Pool과 ForkJoinPool을 응용하고 있습니다. thread 객체를 생성해서 task queue에 등록 후 하나씩 thread 와 매칭 시켜 ForkJoin과 같은 동작 메커니즘방식으로 처리하고 있습니다.
  • 여기서 Task는 Runable이랑, Callable interface입니다.
  • Runable : 일반 void 형태의 동작을 의미
  • Callable : 반환 값이 존재하는 것들을 의미 -> 대부분 Runable interface를 상속받은 다른 adapter class에 등록해서 사용합니다
    • ForkJoin: AdaptedCallable class에 등록 해서사용, FutureTask와 같이 Runable interface를 구현한 구현체에 adapter로 연결해서 사용함

Thread 동작 방식

  • Forkjoin을 통해서 분할 정복방식으로 반복되는 연산을 여러 Thread에 분산키셔서 작업하는 방식
  • Runnable에 있는 로직을 그냥 실행하는 방식

2. Thread Pool

정의

  • java 5버전부터 도입
  • 기존에 thread를 유저가 직접생성해서 구현해서 사용하였지만, java 5 부터는 concurrent 패키지가 포함되면서 thread를 미리 생성하고 관리하는 pool이 생겨남
  • 쓰레드를 허용된 개수만큼만 생성하고 사용할 수 있도록 제약을 주는 것이다

특징

  • 무제한 적으로 쓰레드 생성을 맊고 관리하기 위해서 사용
  • JVM의 옵션등으로 제어할 수 없고 어플리케이션이 선택적으로 사용하는 방식이다
  • 캐시 방식으로 생성하게 될 경우 요청이 들어 올 경우 자동으로 thread를 생성하고, 처리 완료가 된 후에 1분 정보 삭제가 되지 않습니다. 그리고 1분 내로 다른 요청이 들어오면 캐시로 삭제 되지 않은 thread 를 할당해주는 방식도 존재합니다.

구조

  • Task Queue: Task의 요청을 받아서 저장하는 곳
  • Manager: 실제 Thread를 생성하고 관리하는 곳
  • 동작 부분: Task를 Queue에서 꺼내와서 실제 쓰레드를 동작 시켜 결과를 얻는 부분

3. ForkJoin Framework

정의

  • java 7부터 도입됨
  • 큰 업무를 작은 업무로 나누어 배분해서 일은 한 후에 일을 취합해서 실행 하는 실행 메커니즘 입니다.
  • 분할 정복 알고리즘과 비슷하다고 생각하면 됩니다.

특징

  • CPU를 최대로 활용하면서 동기화와 GC를 피할 수 있는 여러기법들이 사용됨
  • 주로 반복적인 작업을 분할 정복을 통해서 취합하는 방식을 사용하기 때문에 stream 에서 parallel을 사용할 경우 ForkJoin으로 데이터를 처리하도록 로직이 실행 됩니다.

실행 과정

  • 큰 업무를 작은 단위로 쪼개서 사용
  • 부모 쓰레드로 부터 처리로직을 복사하여 새로운 쓰레드에서 쪼개진 업무를 수행(Fork)
  • 쪼개는 것을 반복하다가, 특정 쓰레드에서 더이상 Fork가 일어 나지 않고 업무가 완료 되면 그 결과를 부모 Thread에서 join하여 값을 취합
  • 값을 취합 하는 것을 반복

핵심 기능(Work-Strealing)

  • 기본적으로 newCachedThreadPool이나 newFixedThreadPool처럼 ExecutorService의 구현체 입니다.
  • 기본적인 ExecutorServicer과 차이점은 work-stealing 알고리즘이 구현되어 있다는 점
  • 이유 : cpu자원을 효율적으로 사용하기 위해서
    • Idle상태의 CPU시간이 많아 지지 않도록 함

  • 방식
    • Task가 들어와서(submit) 처리 단계에서 Fork를 해 A, B로 나눠지게 됩니다.
    • 2개의 thread(A,B)는 dequeue를 내부에 가지며 task를 등록해서 사용하게 됩니다.
    • A,B중에 먼저 모든 처리를 끝낸 것이 존재할 경우 (예시 : A는 4개의 task 존재, B: 0개) cpu는 idle 상태가 존재하게 됩니다.
    • 이때 B가 A의 테스크일부를 가져와서 처리하게 됩니다(stealing 훔치다)
    • 이과정으로 cpu idle 시간을 줄일려고 노력 합니다.
반응형

'CS > Java' 카테고리의 다른 글

SOLID 원칙  (0) 2022.02.06
예외(Exception)  (0) 2022.01.20
함수형 프로그래밍  (0) 2022.01.18
LocalDatetime, LocalDate, LocalTime  (0) 2022.01.12