고유락(Intrinsic Lock)
Java에서 고유락(intrinsic lock)은 monitor lock 으로 불리기도 하며, 멀티스레드 환경에서 동기화를 달성하기 위해 사용되는 내부적인 잠금 매커니즘이다. 고유락은 객체당 단 하나만 부여되며, synchronized 키워드를 이용하여 여러 스레드를 동기화 시킬 수 있다.
사용예시는 다음과 같다.
public static int counter = 0; // 공유자원
public synchronized void increment(){ // 고유락
counter++;
}
public static void process(){
Thread t1 = new Thread(new Runnable(){
@Override
public void run(){
for(int i=0;i<10;i++){
increment();
}
}
});
Thread t2 = new Thread(new Runnable(){
@Override
public void run(){
for(int i=0;i<10;i++){
increment();
}
}
});
//스레드 실행
t1.start();
t2.start();
t1.join();
t2.join();
}
t1과 t2는 counter라는 공유자원에 동시에 접근하고 있지만 increment() 메소드는 synchronized 키워드로 인해 고유락에 묶여있기 때문에 오직 하나의 스레드만 공유자원에 접근이 가능하다. 따라서 프로그램을 안정적으로 실행할 수 있게 된다.
사용예시
하지만 위의 코드에는 약간의 문제점이 있다. 만약 한 개의 클래스에 두 개 이상의 synchronized 키워드를 가진 메소드가 정의되어 있다면 한 개의 메소드가 동기화 처리될 때 다른 메소드는 동기화 처리되지 않는다. 왜냐하면 고유락은 객체당 하나만 있기 때문에 특정 클래스의 synchronized 메소드가 실행되는 동안 해당 객체의 모든 다른 synchronized 메소드는 고유락을 사용할 수 없게 되어 동기화 처리가 되지 않는다. 이는 성능문제와 데드락(Deadlock)이 일어날 수 있어서 메소드 선언부에 synchronized 키워드를 사용하는 것은 피해야한다.
이러한 문제점을 막기 위해서는 synchronized 키워드를 메소드 선언부에 사용하지 않고, 메소드 내부에 필요한 부분에만 사용해야한다.
예시는 다음과 같다.
public class Example {
private Object lock = new Object(); // 동기화에 사용될 객체
public void synchronizedMethod1() {
synchronized (lock) { // synchronized 키워드를 블록처리함
// 코드
}
}
public void synchronizedMethod2() {
synchronized (lock) { // synchronized 키워드를 블록처리함
// 코드
}
}
}
synchronized 키워드를 메소드의 선언부에 사용하는 것이 아니라, 메소드 내부에 synchronized블록을 사용하여 단일락으로서 사용하게 한다. synchronized를 단일 블록으로 사용하게 되면 해당 블록 내에서만 동기화가 이루어지고 다른 synchronized 블록은 영향을 받지 않는다.
'Programming > Process & Multi Threading' 카테고리의 다른 글
[Java] Executors로 스레드 관리하기 (0) | 2024.02.04 |
---|---|
Mutext 뮤텍스 vs Semaphore 세마포어 (0) | 2024.01.09 |
[Java] 스레드와 메모리구조 그리고 프로세스(Process)의 구조 (0) | 2023.12.16 |
[Java] 스레드의 우선순위(Thread Priority) (0) | 2023.12.15 |
[Java] Main Thread(메인 스레드)와 Worker Thread(작업 스레드) 그리고 Daemon Thread(데몬 스레드) (0) | 2023.12.13 |