Java

Thread safety

Sigfriede 2024. 1. 17. 12:00

  프로그램을 실행하면 OS로부터 실행에 필요한 자원을 할당받아 프로세스가 된다. 쓰레드는 프로세스를 구성하는 것 중 하나이다. 프로세스의 자원을 이용하여 실제로 작업을 수행하는 역할이다. 모든 프로세스에는 하나 이상의 쓰레드가 존재한다. 쓰레드가 하나일 때 싱글 쓰레드, 둘 이상일 때 멀티 쓰레드라고 부른다.

  멀티 쓰레딩의 장점으로는 CPU의 사용률을 향상시키고, 자원을 보다 효율적으로 사용할 수 있고, 사용자에 대한 응답성이 향상되고, 작업이 분리되어 코드가 간결해진다는 점 등이 있다. 그러나 이에 장점만 있는 것은 아니다. 하나의 쓰레드에 문제가 생기면 전체 프로세스에 영향을 주기도 하며, 쓰레드를 많이 생성할 경우 잦은 전환(Context Swiching)으로 인해 성능 저하가 발생할 수 있다. 또 자원 공유를 위해 별도의 작업이 필요한 프로세스와 달리 쓰레드는 같은 프로세스라면 자원(code, data, heap 영역)을 공유하기 때문에 코드가 비정상적으로 동작하기도 한다. 쓰레드 세이프란, 어떤 쓰레드가 함수를 호출하여 동작하고 있을 때 다른 쓰레드가 같은 함수를 호출하여 동작해도 올바른 결과를 도출할 수 있는 것을 의미한다.

  예를 들어 해시맵(HashMap)과 해시테이블(Hashtable), 스트링빌더(StringBuilder)와 스트링버퍼(StringBuffer)를 비교할 수 있다. 각각 후자의 경우 멀티 쓰레딩 환경에서도 정상적으로 동작하기 때문에 쓰레드 세이프하다고 한다. 코드를 직접 확인하면 차이를 명확히 알 수 있다.

 

HashMap과 Hashtable의 구현 코드 비교

 

  쓰레드 세이프하다고 한 해시테이블에는 public 뒤에 synchronized가 추가로 붙어있다. 이는 지정된 영역의 코드를 한 번에 하나의 쓰레드가 수행할 수 있도록 보장한다. 이를 통해 동시성 이슈를 해결하는 것이다. 물론 이미 구현되어 있는 코드 외에도 같은 방법으로 임계영역을 설정해줌으로써 쓰레드 세이프한 코드를 작성할 수 있다.

  그러나 쓰레드 세이프하지 않은 기능이 쓰레드 세이프한 기능보다 효율적이고 성능적으로 우수하기 때문에 싱글 스레드 환경이라면 굳이 쓰레드 세이프한 기능 혹은 코드를 고집할 필요는 없다.

'Java' 카테고리의 다른 글

[Java] 접근 제어자(access modifier)  (0) 2024.01.24
[Java] 제어자(modifier)  (0) 2024.01.22
[Java] 오버로딩(overloading)과 오버라이딩(overriding)  (0) 2024.01.19
자바의 실행 과정  (1) 2023.12.11