Skip to content

wmi review3

myeongin edited this page Jun 13, 2016 · 5 revisions

우명인 3번째 리뷰

Scala Lazy Evalution

lazy라는 키워드는 값이 실제 필요할 때까지 계산을 유예해야 함을 표시한다. method와 차이점이 있다면 method는 호출 될때마다 연산을 재 실행 하지만 lazy 는 최초에만 연산이 수행되고 이후에는 재 사용 된다.

scala> object Demo {
           lazy val x = { println("initializing x"); "done" }
}
  defined module Demo
  scala> Demo
  res5: Demo.type = Demo$@11dda2d
  scala> Demo.x
  initializing x
  res6: java.lang.String = done

lazy는 두번 계산하지 않는다. 실제로 재 호출 된다면 이전에 저장 했던 값을 재 사용한다.

scala> val x = { println("x"); 15 }
x
x: Int = 15

scala> lazy val y = { println("y"); 13 }
y: Int = <lazy>

scala> x
res2: Int = 15

scala> y
y
res3: Int = 13

scala> y
res4: Int = 13

그렇다면 모든 변수를 lazy로 만드는 것이 더 좋지 않은가? 실제로는 비용이 비싼 경우가 아니라면 속도가 빠르지 않기 때문이다.
지연값은 가드를 사용한다.

가드

가드를 사용해서 지연값이 초기화되었는지 여부를 저장해둔 볼러틀(volatile) 필드를 검사하고, 꼭 필요할 때만 지연값을 초기화한다. 또한 초기화하는 과정에서는 이중 검사 락(double checked locking)을 사용해서 혹시 다중 스레드 환경 등에서 이중으로 지연값이 초기화되지 않게 보장한다. 다만 여기에는 성능문제 이외에 다른 단점이 존재한다.
이중 검사 락에서는 지연값이 들어 있는 객체를 모니터로 사용한다. 따라서 지연값이 여럿 들어있는 객체를 사용하는 여러 스레드가 동시에 여러 지연값을 참조하거나, 한 스레드가 지연값을 갱신하는 사이에 다른 스레드가 지연값이 들어 있는 개체에 대해 synchronized를 실행하는 경우 교착상태에 빠질 수 있다.

Clone this wiki locally