728x90
자바에서 모든 객체는 monitor를 가지고 있다.
monitor는 여러 스레드가 객체로 동시에 객체로 접근하는 것을 막는다.
여기서 모든 객체가 중요하다. heap 영역에 있는 객체는 모든 스레드에서 공유 가능하기 때문이다.
스레드가 monitor를 가지면, monitor를 가지는 객체에 lock을 걸 수 있다.
그렇게 되면 다른 thread들이 해당 객체에 접근할 수가 없게된다.
아래 코드를 살펴보자
class Hello implement Runnable {
@Override
public void run() {
String hello = "hello";
synchronized (hello) {
System.out.println(hello);
}
}
}
monitor를 가질 수 있는 것은 synchronized
키워드 내에서 가능하다
여기서 hello라는 String 객체가 synchronized
에 파라미터로 들어가면서, thread가 hello 객체의 monitor를 가질 수 있게 된다
hello라는 객체가 스레드에 의해 공유될 수 있는 객체라고 생각하면 된다.
위의 코드를 decompile하면 조금더 명확해진다
synchronized 구문을 기점으로 monitorenter
와 monitorexit
instructor가 보인다
monitorenter
- 스레드가
monitorenter
instructor를 가르키면 monitor의 소유권을 얻게된다
monitorexit
- 스레드가
monitorexit
instructor를 가르키면 monitor을 놓아준다 - 이 때 다른 스레드들이
monitorenter
를 할 수 있게 되면서 monitor를 얻게된다
즉, monitor의 라이프사이클은 synchronized
키워드에 의존된다.
그래서 객체가 가지는 wait()
, notify()
, notifyAll()
메소드는 모두 synchronized
블록에서만 유의미하다.
해당 메소드들로 스레드를 waitset
에 넣거나, waitset
에서 부터 불러 올 수 있게 된다.
출처
728x90