본문 바로가기

# 02/코틀린

[Kotlin] 동기화를 위한 코드 구현 람다식 활용

반응형

동기화를 위한 코드 구현하기



동기화?


- 변경이 일어나면 안 되는 특정 코드를 보호하기 위한 잠금 기법

- 동기화로 보호되는 코드는 임계 영역(Critical Section)

- Lock을 활용해 임계 영역을 보호


변수를 사용하는 루틴이 많을때 변경될 수 있는 가능성이 많으므로 공유되는 부분을 보호하기 위해 동기화로 잠궈놓는 것임.


여러개의 루틴이 접근하려고 할때 A 루틴이 먼저 접근시 다른 스레드 등이 접근하지 않도록 잠그는 방식



자바의 Lock과 ReentrantLock


Lock lock = new ReentrantLock();

lock.lock();                                // 잠금

try {

                                       // 보호할 임계 영역의 코드

                                       // 수행할 작업

} finally {

lock.unlock();                      // 해제

}


Lock은 여러가지 락 관련 함수를 정의한 인터페이스이며 ReentrantLock은 Lock을 구현한 것으로 synchronized를 사용한다.


선점(preemtive)이란 다른 스레드나 프로세스를 중단 시키는 행위로 OS의 스케줄러가 담당한다.




ReentrantLock를 활용해 특정 함수 보호


- 고차함수를 이용해 구현


// <T> 제네릭 표현 - 특정 자료형을 지정하지 않고 다양한 자료형을 받아들이는 방식

// 매개변수 reLock, body(람다식) 두 개 있음

fun <T> lock ( reLock : ReentrantLock, body : () -> T) : T {

reLock.lock()

try {

// 임계 영역

return body()

} finally {

reLock.unlock()

}

}

// 여기서는 제네릭은 람다식 함수에 지정된 어떤 자료형도 이용할 수 있다.


var sharable = 1                     // 보호가 필요한 공유 자원


fun main() {

val reLock = ReentrantLock()


// 1,2,3 표현식이 모두 동일

lock ( reLock, { criticalFunc() } )     // 1번

lock ( reLock ) { criticalFunc() }     // 2번

lock ( reLock, ::criticalFunc )         // 3번


println ( sharable )

}


// 임계 영역

fun criticalFunc() {

// 공유 자원 접근 코드 사용

sharable += 1

}



코드의 증가 연산을 Atomic 변수로 만들어서 하면 단 1회의 연산을 보장한다. 이것을 원자 변수라고 한다. 나중에 다시 나옴!


반응형