2025. 6. 19. 07:53ㆍJava
면접을 준비하다가 synchronized에 대해 깊이 알고 가면 좋을 것 같아 정리한다.
synchonized 키워드가 어디에 붙는지에 따라 의미가 약간씩 변한다고 하는데 이 부분을 자세히 살펴보자.
synchronized는 lock을 사용해 동기화를 시킨다.
하지만 사용 방식에 따라 혼동되기 쉽다.
synchronized는 4가지의 사용법이 있다.
sychronized method, static sychronized method, sychronized block, static synchonized block.
이 포스팅에서는 이 4가지 방식의 차이인 lock이 적용되는 범위를 중점으로 다룬다.
synchonized method (클래스의 인스턴스에 lock을 검)
synchronized method는 클래스의 인스턴스에 대하여 lock을 건다. 다음과 같은 상황을 보자.
순서대로 lock을 획득하고 반납하였다.
이번엔 각각의 인스턴스를 만들고 메서드를 실행시켜보자.
이 상황에서는 lock을 공유하지 않기 때문에 동기화가 발생하지 않는다.
코드 결과를 보면 알 수 있듯이 synchronized method는 인스턴스에 대하여 lock을 건다. 인스턴스에 대해서 lock을 건다고는 표현이 인스턴스 접근 자체가 lock이 걸리는 것인지 혼란스러울 수 있는 데 그렇지 않다. 다른 예시를 보자.
여기서 synchronized가 적용되지 않은 print()메서드를 추가하고 lock이 걸린 중간에 호출해봤다.
결과는 run()메서드의 lock과 상관없이 정상적으로 호출된다.
만약 print()메서드도 synchronized가 적용되어있다면 어떻게 될까?
이번에는 동기화가 발생했다.
결과를 정리해보자면 synchronized method는 인스턴스 단위로 lock을 건다. 이때, synchronized가 적용된 모든 object에 대해서 lock을 공유한다.
static synchronized method (클래스 단위로 lock발생)
static이 포함된 synchronized method방식은 우리가 일반적으로 생각하는 static의 성질을 갖는다. 인스턴스가 아닌 클래스 단위로 lock이 발생한다.
다른 인스턴스이지만 클래스 단위로 lock이 발생했다. 만약, static synchronized method와 synchronized method가 섞여있다면 어떨까?
인스턴스 단위의 lock과 클래스 단위의 lock은 공유되지 않았다.
static synchronized method를 정리해보면 클래스 단위로 lock을 걸지만,
인스턴스 단위의 synchronized method와 lock을 공유하지 않는다.
synchronized block (인스턴스 단위로 lock, lock객체를 지정)
synchronized block은 인스턴스의 block단위로 lock을 건다. 이때, lock객체를 지정해줘야한다.
이렇게 block을 지정해준다. 이때 this는 A객체를 의미하고 block이 method전체에 적용되어있기 때문에 method단위로 lock을 거는 것과 같다.
하지만 위와 같이 여러 로직이 섞여있는 사이에 필요한 부분만 lock을 걸 수 있다.
lock은 synchronized block에 진입할 때 획득하고 빠져나오면서 반납하므로 block으로 범위를 지정하는게 더 효율적이다.
synchronized block도 method와 동일하게 인스턴스에 대해서 적용된다. 따라서 다음과 같은 상황에서 lock은 각각의 인스턴스별로 관리된다.
이번에는 lock 객체를 인스턴스가 아닌 class로 사용해보자.
block에 .class형식을 사용하면 인스턴스가 아닌 class단위로 lock을 건다.
정리하자면, synchronized block은 lock을 거는 객체를 지정할 수 있다.
객체를 넘기면 인스턴스 단위로 lock을 걸고 .class형식으로 넘기면 클래스 단위의 lock을 건다.
static synchronized block (클래스 단위로 lock발생)
static method안에 synchronized block을 지정할 수 있다. static의 특성상 this같이 현재 객체를 가르키는 표현을 사용할 수 없다.
static synchroinzed method방식과 차이는 lock객체를 지정하고 block으로 범위를 한정지을 수 있다는 점이다.
이외에 클래스 단위로 lock을 공유한다는 점은 같다.
synchronized는 thread별 동기화 순서를 보장할까?
순서를 보장하지 않는다.
정리해보면, sychronized method, sychronized block 는 인스턴스 단위로 lock이 걸리며,
static sychronized method, static synchonized block 는 클래스 단위로 lock이 걸린다.
block은 객체를 지정할 수 있으며, 범위를 메소드보다 더 좁게 설정할 수 있다.
'Java' 카테고리의 다른 글
Java 8 버전 이후 새로운 기능 정리 및 코드 예제 (2) | 2025.06.17 |
---|---|
JVM (0) | 2025.02.27 |
java동작 과정 (0) | 2024.01.16 |