Replies: 2 comments
-
|
synchronized는 동시성을 크게 두 가지 방식으로 보장합니다. 첫째, 같은 락을 기준으로 한 번에 하나의 스레드만 synchronized 영역에 들어가게 합니다. 둘째, 락을 해제하고 다시 획득하는 과정에서, 그래서 synchronized 락이란 무엇인가?
조금 더 정확히는, 자바의 모든 객체는 내부적으로 모니터 락을 가질 수 있고, 어떤 스레드가 다른 스레드가 같은 락을 사용하는 즉, 핵심은 아래와 같습니다. 왜 synchronized가 필요한가?멀티스레드 환경에서는 여러 스레드가 같은 공유 자원을 동시에 수정할 수 있습니다. 예를 들어 두 스레드가 동시에 이 작업을 수행하면 둘 다 같은 값을 읽고, 각각 증가시킨 값을 저장할 수 있습니다. 두 번 증가했으니 기대값은 2인데, 실제 결과는 1이 될 수 있습니다. 이런 문제를 경쟁 상태라고 볼 수 있고, 원인은 공유 자원에 대한 읽기-수정-쓰기 작업이 원자적으로 실행되지 않기 때문입니다.
synchronized는 어떻게 동시성을 보장하는가?
첫 번째는 상호 배제입니다. 하나의 스레드가 락을 획득하면, 다른 스레드는 같은 락을 사용하는 임계 영역에 들어갈 수 없습니다. 이렇게 공유 자원에 대한 접근이 순차적으로 일어나기 때문에 동시에 수정하면서 값이 꼬이는 문제를 막을 수 있습니다. 두 번째는 가시성 보장입니다. 멀티스레드 환경에서는 한 스레드가 변경한 값이 다른 스레드에게 바로 보이지 않을 수 있습니다.
즉, synchronized 사용 방식
인스턴스 메서드에 붙이면 현재 객체, 즉 public synchronized void increase() {
count++;
}위 코드는 아래와 비슷하게 이해할 수 있습니다. public void increase() {
synchronized (this) {
count++;
}
}블록으로 사용하면 필요한 코드 영역만 임계 영역으로 좁힐 수 있습니다. private final Object lock = new Object();
public void increase() {
synchronized (lock) {
count++;
}
}또한 별도의 락 객체를 사용할 수도 있습니다. privatefinalObjectlock=newObject();
publicvoidincrease() {
synchronized (lock) {
count++;
}
}이 방식은 외부에서
public static synchronized void increaseGlobalCount() {
globalCount++;
}이는 아래와 비슷하게 동작합니다. synchronized (Counter.class) {
globalCount++;
}주의할 점
임계 영역이 너무 크면 한 번에 하나의 스레드만 실행할 수 있는 구간이 길어집니다. 그만큼 대기하는 스레드가 많아지고 성능이 떨어질 수 있습니다. 예를 들어 오래 걸리는 작업 전체를 public synchronized void process() {
// 오래 걸리는 로직
// 외부 API 호출
// 공유 자원 변경
}이런 경우에는 정말 보호해야 하는 공유 자원 접근 부분만 또 여러 락을 중첩해서 사용할 경우에는 서로가 서로의 락을 기다리는 데드락 가능성도 고려해야 합니다. 정리결론적으로 저는
즉, |
Beta Was this translation helpful? Give feedback.
-
1. synchronized락이란?synchronized는 자바 초기 버전부터 제공하는, 동시성을 제어하기 위한 키워드입니다. synchronized를 사용하면 원하는 임계 영역의 동기화를 간단하게 구현할 수 있습니다. 2. synchronized는 어떻게 동시성을 보장하는가?우선 자바의 모든 객체는 내부에 자신만의 락을 가지고 있습니다. 해당 락을 모니터락이라고 부르며 내부적으로는 뮤텍스로 동작합니다.(해당 락에 대한 구체적인 내용은 생략하겠습니다.) synchronized는 동기화 블럭 전 후로 해당 모니터락을 사용하여 여러 스레드의 자원 동시 접근을 막습니다. 구체적으로 특정 스레드가 synchronized 내부에 진입하면, 해당 객체의 모니터 락을 획득하고 블록을 벗어날 때 락을 해제하게 됩니다. 결국, 스레드가 객체의 모니터 락을 획득하려고 시도할 때 이미 다른 스레드가 이 락을 보유하고 있다면, 현재 스래드는 락이 해제될 때까지 대기 모드에 들어가게 됩니다. 3. (추가)synchronized의 단점synchronized는 앞서 말했다시피, 자바의 초창기버전부터 동시성 제어를 위해 등장한 키워드라 동기화를 구현하는 가장 기본적인 방법입니다. 따라서, 문법으로 제공되어 사용하기 편하다는 장점과 명시적으로 락을 획득하고 해제하는 코드를 작성하지 않아도 된다는 점에서는 큰 장점입니다. 하지만, 2가지 문제를 갖고 있습니다.
추가 학습 래퍼런스synchronized의 설명과 한계에 대해서 아래 블로그에 구체적으로 작성되어 있어 공유합니다! 여기에 더해 synchronized의 한계를 극복하기 위해 등장한 Lock 인터페이스와 ReentrantLock 클래스에 대해서도 학습해보면 좋을 것 같아 함께 공유합니다! 동시성 제어를 위한 synchronized 키워드의 의미와 한계점 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Beta Was this translation helpful? Give feedback.
All reactions