프로그래밍백엔드 개발자

Java에서 synchronized 메커니즘은 어떻게 작동합니까? 언제 적용해야 하며 리소스에 대한 접근을 동기화할 때 어떤 문제점이 있습니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

질문의 역사:

Java가 등장하면서 개발자들은 공유 리소스에 대한 경쟁 접근 문제에 직면하게 되었습니다. 이를 해결하기 위해 좀 더 고급 동기화 원시 데이터 유형이 도입되었으며, 그 중 가장 중요한 것은 키워드 수정자 synchronized입니다.

문제:

동기화 없이 다중 스레드 애플리케이션에서 공유 리소스가 손상될 수 있습니다. 데이터 경합이 발생하며 객체의 상태가 예측 불가능해집니다.

해결책:

synchronized는 메서드나 코드 블록에 대한 모니터를 설정하여 특정 시점에 하나의 스레드만 임계 영역에 접근할 수 있도록 합니다. 스레드 동기화는 메서드 수준 또는 블록 수준에서 구현될 수 있습니다.

객체 잠금 예:

public class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } }

블록도 동기화할 수 있습니다:

public void safeIncrement() { synchronized(this) { count++; } }

주요 특징:

  • 메서드 동기화는 this 수준에서의 동기화와 동일합니다.
  • 정적 메서드에 대한 동기화는 클래스 객체에 대해 수행됩니다.
  • 임계 영역의 범위를 최소화해야 합니다.

블록을 염두에 둔 질문.

synchronized 메서드와 synchronized 블록의 차이점은 무엇입니까?

synchronized 메서드는 현재 객체(this) 또는 클래스(정적 메서드의 경우) 전체를 차단합니다. 블록은 필요한 코드의 특정 부분만 동기화할 수 있으며 잠금을 위한 객체를 선택할 수 있습니다.

두 개의 서로 다른 스레드가 동일한 객체의 두 가지 다른 synchronized 메서드에 동시에 진입할 수 있습니까?

아니요, 메서드가 동일한 모니터(this)에 동기화되어 있다면 그렇지 않습니다. 서로 다른 모니터를 사용하는 경우에는 가능합니다.

synchronized 수정자는 스레드 간의 변수 가시성에 영향을 줍니까?

예, synchronized 블록에 들어가면 스레드의 캐시가 무효화되고 변수의 값이 업데이트됩니다 (발생 순서 관계).

전형적인 오류 및 안티 패턴

  • 너무 "넓은" 객체(예: String 또는 class 객체)에서의 동기화
  • 동기화된 블록 내의 코드가 오랫동안 실행됨
  • synchronized 블록과 비동기 코드 사이의 동일한 리소스에 대한 접근 혼합

실생활 예

부정적인 사례

개발자가 클래스의 정적 메서드를 인스턴스 개체에서 동기화하여 서로 다른 인스턴스를 사용할 때의 정확성을 보장하지 않습니다.

장점:

  • 간단한 구현

단점:

  • 스레드 간의 예상치 못한 데이터 경합
  • 잡아내기 힘든 버그

긍정적인 사례

공유 리소스를 사용하는 모든 메서드가 하나의 객체 모니터에서 동기화되며, 임계 영역은 최소화됩니다.

장점:

  • 스레드가 일관된 데이터로 작업합니다.
  • 최소한의 차단

단점:

  • 상호 차단(deadlock) 분석 및 유지 관리를 더 어렵게 합니다. 특히 많은 동기화된 객체가 있을 때 더욱 그렇습니다.