Thread 동기화

- 멀티 스레드에서, 여러 스레드가 하나의 객체를 공유해서 써야 하는 경우 사용

- 공유 자원의 문제가 발생 -> ex 예약 시스템

- 스레드가 사용 중인 객체를 다른 스레드가 변경할 수 없도록, 객체에 잠금을 걸어주어야 한다.

- 임계 영역(critical section)을 설정해서 문제 해결 -> lock 개념 도입

- 임게 영역 : 단 하나의 스레드만 실행할 수 있는 코드 영역

 

스레드 동기화 방법

- 임계 영역(critical section) : 공유 자원에 단 하나의 스레드만 접근하도록(하나의 프로세스에 속한 스레드만 가능)

- 뮤텍스(mutext) : 공유 자원에 단 하나의 스레드만 접근 가능하도록(서로 다른 프로세스에 속한 스레드도 가능)

- 이벤트(event) : 특정한 사건 발생을 다른 스레드에게 알린다.

- 세마포어(semaphore) : 한정된 개수를 가진 자원을 여러 스레드가 사용하려고 할 때 접근 제한

- 대기 기능 타이머(waitable timer) : 특정 시간이 되면 대기 중이던 스레드를 꺠운다.

 

 

 

동기화를 하지 않은 Code

- 스레드 2개가 동시에 실행되기 때문에 잔액이 마이너스가 나온다.

 

동기화 사용 synchronzied keywowrd

- 메소드 자체에 동기화를 하거나, 임의 영역을 설정해서 block으로 닫아주는 방법이 있다.

- 임의 영역을 설정해서 동기화 해주는 방식이 좀 더 사용하기 좋다.

- 공유 객체가 자기 자신인 경우 -> this

 

상태 전이도

- wait() : lock을 걸고 대기

 

notify() Method

- 스레드가 작업을 완료하면 notifiy를 호출해서 일시 정지 상태의 다른 스레드들을 실행 대기 상태로 옮긴다.

- 작업 완료된 스레드(자기 자신)는 wait() 메소드로 일시 정지 상태로 만든다.

- wait에서 대기하고 있는 스레드가 실행할 수 있는 상황이 되어서 block 해제

 

 

Java 고유 락(Intrinsic LocK)

  • 자바의 모든 객체는 lock을 갖고 있다.
  • synchronzied 블록은 Intrinsic lock(고유락)을 사용해서 스레드 접근을 제어한다.
  • synchronzied()
    • 1. 인자 값에 this 이용 : 여러 스레드가 들어와 서로 다른 block 호출해도 this를 사용해서 자기 자신에 lock을 걸어 기다려야 한다.
    • 2. 인자 값에 Object 이용 : block 마다 다른 Lock을 걸리게 해 효율적인 코드 작성 가능
  • structured lock(구조적 lock) : 고유 lock을 통한 동기화
  • reentarant lock(명시적 lock) : A획득 -> B획득 -> A해제 -> B해제를 가능하게 하기 위해서 사용
public class Counter{
    private Object lock = new Object(); // 모든 객체가 가능 (Lock이 있음)
    private int count;
    
    public int increase() {
        // 단계 (1)
        synchronized(lock){	// lock을 이용하여, count 변수에의 접근을 막음
            return ++count;
        }
        
        /* 
        단계 (2)
        synchronized(this) { // this도 객체이므로 lock으로 사용 가능
        	return ++count;
        }
        */
    }
    /*
    단계 (3)
    public synchronized int increase() {
    	return ++count;
    }
    */
}

+ Recent posts