Java synchronized란?

Ilhwanee·2022년 10월 3일
1

Java

목록 보기
4/13
post-thumbnail

멀티 스레드 환경에서 여러 스레드가 동시에 데이터에 접근한다면 의도하지 않은 결과가 발생할 수 있다.

이러한 이유로 synchronized는 공유된 가변 데이터를 보호하기 위하여 사용된다.

보호하는 방법은 단순히 동기화처리하여 한 자원에 한 스레드만 동시에 접근할 수 있게 하는 것이다.

synchronized를 사용하는 방법은 다음과 같다.

  • 인스턴스 메소드 동기화
    public synchronized void method(){}
  • 스태틱 메소드 동기화
    public static synchronized void method(){}
  • 메소드 안 동기화
    // 메소드 안에서
    synchronized(this) {}

synchronized가 적용된 구문을 synchronized block이라고 한다.

멀티 스레드 환경에서 동기화로 Race condition을 해결해준다는 장점이 있지만, 성능이 크게 저하될 수 있으니 적재적소에 사용해야한다.

다음은 synchronized의 동기화 방법들이다.



인스턴스 메소드 동기화

public synchronized void method(){}

메소드에 synchronized를 적용하기 때문에 해당 메소드만 동기화 된다고 착각할 수 있다.

하지만 인스턴스 메소드 동기화는 해당 메소드에 접근하면 끝날때까지 인스턴스 접근을 아예 막는다.

예를 들어 한 스레드가 어떠한 인스턴스의 synchronized가 적용된 메소드1 수행을 시작했다면, 다른 스레드는 메소드2를 수행하고 싶어도 대기한다.

즉, 하나의 인스턴스를 동기화할 수 있다.



스태틱 메소드 동기화

public static synchronized void method(){}

인스턴스 메소드 동기화가 하나의 인스턴스를 동기화 시켰다면, 스태틱 메소드 동기화는 해당 객체 전체를 동기화 시킨다.

예를 들어 하나의 클래스를 찍어낸 여러 인스턴스가 존재하고, 인스턴스1이 syncronized가 적용된 메소드를 수행 시작했다면, 다른 스레드에서 인스턴스2를 사용하고 싶어도 대기한다.

즉, 동일한 클래스로 만들어진 여러 인스턴스들을 모두 동기화할 수 있다.



메소드 안 동기화

// 메소드 안에서
synchronized(this) {}

위 두 방법들은 인스턴스 하나 혹은 전체를 동기화시켜 비효율적이다.

메소드 안 동기화 방법을 사용하면 synchronized 구문에서 사용된 멤버 필드를 접근하는 경우에만 동기화한다.

예를 들어 한 스레드가 인스턴스의 멤버 필드 number을 증가시키는 synchonized 구문을 실행한다면

다른 스레드는 해당 인스턴스의 number을 감소시키는 메소드는 실행하지 못하고 대기하지만, number에 접근하지 않는 메소드는 대기 없이 실행 가능하다.



profile
블로그 이전 -> https://pppp0722.github.io

0개의 댓글