태그 보관물: thread-safe

스레드-안전(Thread-safe)과 재진입가능(Reentrant)의 차이

다중 스레드 프로그래밍을 하다 보면, 스레드-안전(Thread-safe)과 재진입가능(Reentrant)이란 용어를 보게 된다. 처음에는 이 두 용어에 대한 개념이 명확하지 않게 느껴지지만, 명확한 차이가 있다. 우선 이 두 개념에 대한 정의를 살펴보자.

1. 스레드-안전(Thread-safe) 정의
스레드 안전은 다중 스레드가 동시에 같은 로직을 실행하는 경우에도 결과가 정확함을 보장한다는 것이다. 따라서 여러 스레드가 클래스에 접근할 때, 실행 환경이 해당 스레드들의 실행을 어떻게 스케줄 하든 어디에 끼워 넣든, 호출하는 쪽에서 추가적인 동기화나 다른 조율 없이도 정확하게 동작하면 해당 클래스는 스레드 안전하다고 말한다.

2. 재진입가능(Reentrant) 정의
재진입가능은 다중 스레드가 동시에 같은 로직을 실행할 수 있도록 구현해서 스레드-안전을 확보하는 형태이다.

위에서 정의한 내용을 토대로, 재진입가능한 로직은 스레드-안전을 확보해서, 스레드-안전을 확보하는 하나의 수단이 된다. 하지만 스레드-안전을 확보하는 수단은 재진입가능한 로직외에도 여러 동기화 기법이 있다.

자바에서 스레드-안전한 로직을 구현하는 방법은 다음과 같다.
– Atomic 시리즈의 클래스 사용
– 뮤텍스 사용
– 세마포어 사용
– 아래의 재진입가능한 로직을 구현한 형태 사용

자바에서 재진입가능한 로직을 구현한 형태는 다음과 같다.
– 암시적인 락 : 기본적으로 자바 객체는 모니터 락을 가지고 있고, 이것으로 재진입가능한 로직의 형태로 사용할 수 있다.
– ReenterantLock과 ReentrantReadWriteLock의 사용

* Reference
– 자바 병렬 프로그래밍

Synchronized, ReentrantLock, Thread-Safe 등에 대해서..

아래내용은 http://blog.naver.com/mtorange?Redirect=Log&logNo=130014259906 에서 발췌를 하였습니다.

Reentrant Vs Thread-Safe

1. Reentrant 한 함수는 Thread-Safe하다.
2. Thread-Safe 하다고 해서 Reentrant  하다고 볼 수 없다.
Reentrant 한 함수는 다른 Thread가 재진입을 하건 Signal handler에 의해 재진입을 하건 아무 문제 없이 동작하는 함수이다. 따라서 당연히 Thread-Safe 하다.

반면 Thread-Safe한 함수는 여러 Thread가 동시에 접근할 경우 문제만 없으면 된다.
아래 함수는 Thread-Safe하다고 할 수 있지만 Reentrant하다고 볼 수 없다.

void thread_safe_function()
{
  static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
  static int context;
  pthread_mutex_lock(&mtx);
  context ++;
  pthread_mutex_unlock(&mtx);
}

아래의 내용은 http://mindwing.kr/103 에서 발췌를 하엿습니다.
synchronized 키워드 대신 java.util.concurrent.ReentrantLock 을 쓰면 다음의 잇점들이 생깁니다.

  – lock 을 얻으려는 스레드를 interrupt 시킬 수 있다.
  – lock 을 얻는데 대한 timeout 을 설정할 수 있다.
  – lock 에 2개 이상의 condition 을 설정해서 쓸 수 있다.
  – synchronized 키워드를 위해 JVM 이 사용하는 lock 기능은 하드웨어의 lock 메커니즘과 잘 매핑되지 않는 문제를 피할 수 있다.

둘 중의 무엇을 쓸 것인지는 다음 가이드를 따르면 됩니다.

  – java.util.concurrent 패키지에는 lock 기능을 제공하는 다른 클래스들이 많이 있다.
  – 데이터 구조등의 사용 목적에 따라 이들 클래스를 쓰는 것이 synchronized 키워드나 ReentrantLock 클래스를 쓰는 것보다 낫다.
  – synchronized 키워드로 잘 동작하고 있는 코드거나 그런 코드를 잘 만들 수 있다면 synchronized 키워드를 쓰는 것이 코드 수도 적고, 에러가 발생할 가능성도 낮다.
  – 여러 condition 을 설정해서 써야 한다면 ReentrantLock 클래스를 쓴다.