동기화를 위한 코드 구현하기
동기화?
- 변경이 일어나면 안 되는 특정 코드를 보호하기 위한 잠금 기법
- 동기화로 보호되는 코드는 임계 영역(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회의 연산을 보장한다. 이것을 원자 변수라고 한다. 나중에 다시 나옴!
'# 02 > 코틀린' 카테고리의 다른 글
[Kotlin] 코틀린의 다양한 함수들 1 (0) | 2019.07.05 |
---|---|
[Kotlin] 네트워크 호출 구현 람다식 활용 (0) | 2019.07.05 |
[Kotlin] 다른 함수의 참조에 의한 호출 (0) | 2019.07.04 |
[Kotlin] 고차 함수와 람다식 (0) | 2019.07.04 |
[Kotlin] 함수형 프로그래밍 (0) | 2019.07.04 |