[Java] 고유락 (Intrinsic Lock)

강민승·2023년 8월 30일
0

JAVA

목록 보기
9/15

Java의 멀티스레딩 환경에서 동기화는 필수적입니다. 오늘은 Java의 고유락에 대해 깊게 알아보자

고유락 (Intrinsic Lock)이란?

Java에서의 고유락은 모든 객체가 갖고 있는 내장 락을 지칭한다다. synchronized 키워드를 사용하여 이 락을 활용하면, 여러 스레드가 동시에 데이터에 액세스하는 것을 방지할 수 있다.

고유락 사용 방법

동기화된 메소드:

public synchronized void myMethod() {
    // synchronized block of code
}

위와 같이 synchronized 키워드를 메소드 선언에 추가하면, 해당 메소드는 동기화 된다.

동기화된 블록: 특정 코드 부분만 동기화하려면 아래와 같이 사용한다.

synchronized(someObject) {
    // synchronized block of code
}

예제:

public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

위의 예제에서 increment() 메소드는 synchronized로 선언되었기 때문에 한 번에 한 스레드만이 이 메소드에 접근 가능하다.

고유락의 특징

재진입 가능: 이미 획득한 락을 다시 획득하는 것이 가능합니다. 이 특성은 재귀적인 동기화된 메소드 호출에 유용하다.
예제:

public synchronized void recursiveMethod(int value) {
    if (value <= 0) return;
    recursiveMethod(value - 1);
}

위의 예제에서 recursiveMethod는 동기화되어 있지만, 재진입성 덕분에 재귀 호출이 가능하다.

락의 해제: synchronized 메소드나 블록을 벗어나면 자동으로 락이 해제됩니다.

주의 사항

데드락: 여러 스레드가 서로의 락을 기다리면서 진행이 멈출 수 있다. 이를 데드락이라고 한다.
예제:


Object lock1 = new Object();
Object lock2 = new Object();

Thread thread1 = new Thread(() -> {
    synchronized(lock1) {
        synchronized(lock2) {
            System.out.println("Thread 1");
        }
    }
});

Thread thread2 = new Thread(() -> {
    synchronized(lock2) {
        synchronized(lock1) {
            System.out.println("Thread 2");
        }
    }
});

thread1.start();
thread2.start();

위의 예제에서 thread1과 thread2는 서로의 락을 기다리면서 데드락 상태에 빠질 수 있다.

과도한 동기화: 불필요한 동기화는 성능 저하를 초래할 수 있습니다. 동기화가 필요한 부분만 동기화하는 것이 중요합니다.

결론

Java의 고유락은 멀티스레딩 환경에서 데이터의 일관성을 보장하는데 중요한 도구입니다. 그러나 적절하게 사용되지 않으면 문제점을 초래할 수 있으므로 신중하게 사용해야 합니다.

profile
Step by Step goes a long way. 꾸준하게 성장하는 개발자 강민승입니다.

0개의 댓글