본문 바로가기

개발지/Today I learn

[0908] 자바 스레드 (스레드 제어)

#스레드 제어

- 스레드 동기화

  ▪ 멀티 스레드 프로세스의 경우, 두 스레드가 같은 데이터를 공유하게 될 때 문제가 발생할 수 있다.

  ▪ 스레드 동기화를 통해 두 스레드가 충돌하는 상황을 피할 수 있다.

 

- 임계 영역(Critical section)과 락(Lock)

  ▪ 임계 영역은 하나의 스레드만 코드를 실행할 수 있는 코드 영역이다.

  ▪ 락은 임계 영역을 포함하고 있는 객체에 접근할 수 있는 권한을 의미한다.

  ▪ synchronized 키워드를 통해 특정 코드 구간을 임계 영역으로 설정한다.

   

   (1) 메서드 전체를 임계 영역으로 지정

  -> 메서드 반환 타입 좌측에 synchronized 키워드를 작성하여 메서드 전체를 임계 영역으로 설정한다.

  -> 임계 영역으로 지정된 메서드를 실행하는 스레드는 메서드가 포함된 객체의 락을 얻는다.

  -> 해당 스레드가 객체의 락을 가지고 있는 동안 다른 스레드는 해당 메서드의 코드를 실행하지 못하게 된다.

 

   (2) 특정한 영역을 임계 영역으로 지정

  -> synchronized 키워드와 함께 소괄호() 안에 해당 영역이 포함된 객체의 참조를 넣고, 중괄호{}를 열어 블록 내에 코드를        작성한다.

  -> 임계 영역으로 지정된 메서드를 실행하는 스레드는 객체의 락을 얻고, 임계 영역 내의 코드를 실행한다.

 

- 스레드의 상태와 실행 제어

  ▪ 앞선 코드들에서 사용한 start() 메서드는 스레드를 시작시키는 것이 아닌 실행 대기 상태로 만드는 메서드이다.

  ▪ 즉, 스레드는 여러 상태에 있을 수 있으며, 이런 상태를 바꿀 수 있는 메서드가 존재한다.

 

   (1) sleep(long milliSecond) : milliSecond동안 스레드를 잠시 멈춤.

static void sleep(long milliSecond)

  -> Thread의 클래스 메서드. 스레드의 실행을 잠시 멈출 때 사용.

  -> 실행 정지된 메서드는 인자로 전달한 시간이 경과되면 실행 대기 상태로 복귀한다.

  -> 혹은 interrupt() 메서드를 호출해 실행 대기 상태로 복귀시킬 수 있다. (※이 경우 예외 처리 필수)

 

   (2) interrupt() : 일시 중지 상태인 스레드를 실행 대기 상태로 복귀.

void interrupt()

  -> sleep() , wait(), join()에 의해 일시 정지된 스레드들을 실행 대기 상태로 복귀시킨다.

  -> sleep() , wait(), join() 에 예외를 발생시켜 실행 대기 상태로 만드는 메서드이다. 

  -> 따라서 사용할 때에는 try - catch 문으로 예외 처리를 해주어야 한다.

 

   (3) yield() : 다른 스레드에 실행을 양보.

static void yield()

  -> 다른 스레드에 자신의 실행 시간을 양보한다.

  -> 스레드의 반복 작업이 할당되어 있을 때, 무의미한 반복문의 순회를 막을 수 있다.

 

   (4) join() : 다른 스레드의 작업이 끝날 때까지 기다림.

void join()
void join(long milliSecond)

  -> 특정 스레드가 작업하는 동안 자신을 일시 중지 상태로 만든다.

  -> sleep()과 마찬가지로 try - catch문으로 감싸서 사용한다.

  -> sleep()과는 다르게 특정 스레드 대해 동작하는 인스턴스 메서드이다.

// sleep()의 활용
Therad.sleep(1000);

// join()의 활용
thread1.join();

 

   (5) wait(), notify() : 스레드 간 협업에 사용

  -> 두 스레드가 교대로 작업을 처리해야 할 때 사용한다.

  -> 스레드 A와 B가 교대로 작업하는 경우, A의 작업이 끝난 후 notify()를 호출해 스레드 B를 호출한다.

  -> 이어서 wait()을 통해 A는 일시 정지 상태가 된다.

  -> B의 작업 후 다시 notify()를 통해 A를 실행 대기 상태로 만든 후 wait()을 통해 B는 일시 정지.