🏘

멀티 스레드 환경의 자원 공유에 대하여

스프링 스터디 중에서 나온 의견 나눔에 대한 정리 포스팅입니다.

우선 스레드에 대한 개념에 대해서 간단히 살펴보겠습니다.

스레드에 대하여

스레드란 ?

  • 프로세스 안에서 실행되는 작업 단위

그러면 프로세스는 뭐지 ?

프로세스는 프로그램이 실행 중인 상태입니다. (하나 이상의 스레드를 포함)

프로세스와 스레드의 가장 큰 차이점

프로세스는 운영체제로부터 자신만의 독립적인 고유 공간 + 자원을 할당 받아 동작합니다.

스레드는 한 프로세스내에서 여러 흐름으로 동작하며 프로세스 내의 주소 공간이나 자원을 공유할 수 있습니다.

프로세스 간 : [데이터 영역, 힙, 스택] 모두를 비 공유합니다.
스레드 간 : [데이터 영역, 힙, 스택] 중 스택 영역만 비 공유합니다.

멀티 스레드란 ?

하나의 프로세스를 다수의 실행 단위로 구분하여 자원을 공유하고 자원의 생성과 관리의 중복성을 최소화하여 수행 능력을 향상시키는 것을 멀티 스레드라고 합니다.

즉, 하나의 프로그램에서 여러 일들을 병렬로 처리하기 위함이라고 할 수 있습니다.

멀티 스레드의 장점

  1. 다른 스레드와 공간과 자원을 공유하면서 사용
  2. 프로세스에 비해서 스레드는 빠르게 생성 + 적은 메모리 사용

멀티 스레드의 단점

멀티 스레드는 자원을 공유하기 때문에 서로의 자원을 동시에 접근하려 할 때 서로 교착 상태(Deadlock)에 빠질 수 있다.

따라서, 멀티 스레드 환경에서는 Deadlock이 발생하지 않도록 동기화하는 작업이 필요하다.

동기화 방법에는 여러가지가 있지만 이번 포스팅에서는 다루지 않습니다 !

[본론] 스터디 공유 내용 !

스터디 범위에 ‘싱글톤 레지스트리’ 에 대한 내용을 공유하던 중 아래와 같은 내용이 있었습니다.

스프링의 애플리케이션 컨텍스트는 기본적으로 하나의 객체만 생성하는 싱글톤으로 관리하기 때문에 멀티 스레드 환경에서 값을 변경하는 방식으로 만들지 않는다.

하지만, 다음과 같은 질문이 있었습니다.

만약, 멀티 스레드 환경에서 동작하고 공유 자원이 필요해서 값을 수정해야 할 경우에는 어떻게 처리하는 것이 좋을 까?

첫번째 의견으로는 Java의 synchronized 를 사용하는 방법이 공유되었고

두번째 의견으로는 옵저버 패턴을 사용하는 방법이 공유되었습니다.

Java의 ‘synchronized’를 사용하는 방법

장점

  • 스레드간 동기화가 해결되며 공유 자원에서 컨플릭트가 나지 않는다.

단점

  • synchronized는 쓰레드가 Blocking이 되는 Lock에 걸리기 때문에 성능 저하를 가져온다.

옵저버 패턴을 사용하는 방법

옵저버 패턴을 사용하여 여러 곳을 옵저빙하다가 어느 한 곳에서 변화가 일어나면 이 객체와 관련된 옵저버에게 해당 변화를 전달하는 방식

장점

  • synchronized에 비해서 성능 저하가 발생하지 않는다.

단점

  • 공유 자원의 변경을 전달하는 시간 동안 컨플릭트가 발생할 수 있다.

일관성을 보장하지 않을 수도 있다 !

마무리

개인적으로 공부한 것 + 공유 내용에 관한 포스팅이므로 틀린 부분이 있을 수 있습니다.

봐주셔서 감사합니다 ! 🙇🏻‍♂️