Java

동기와 비동기, Java Synchronized

기기디 2022. 5. 28. 00:00

정의

동기화

  • 동일한 객체나 메소드에 먼저 접근한 쓰레드가 작업을 마칠때까지 나머지 쓰레드는 작업을 수행하지 않고 기다리는 역할을 말한다.
  • 동일한 객체에 접근했을때 먼저 접근한 쓰레드가 작업을 마치기 전까지 다른 쓰레드에 의해서 방해받지 않도록 하는것을 말한다.
  • 프로세스(쓰레드)가 수행되는 시점을 조절하여 프로세스(쓰레드)간 알고 있는 정보가 일치하도록 하는것을 말한다.
  • 정리 : 다수의 작업이 있더라도 순차적으로 작업을 처리하는 방식을 말한다. / 공유자원(객체)을 상대로 순서대로 작업이 이루어지도록 처리하는 방법을 말한다.

비동기

  • 요청과 결과가 동시에 일어나지 않는다를 의미한다. 요청을 보냈을때 응답상태와 상관 없이 다음 동작을 수행하며 응답을 기다리는것이 가능하다. 예시를 들어보자면, 쇼핑몰에서 우측하단에 항상 플로팅버튼의 형태로 채팅상담을 가능
  • 정리 : 다수의 작업이 있을때 비순차적 병렬방식으로 작업을 처리하는 방식을 말한다.

예시

메소드 체이닝 - 동기식처리

  • 하나의 태스크를 여러개의 메소드로 나누어 처리하는 경우, 순차적으로 처리되어야하는 상황이 존재한다. 여러개의 메소드 중 일부메소드는 다른 메소드에서 처리된 데이터를 기반으로 하는 상황이 그렇다. 이럴 경우 콜백함수나 메소드체이닝의 방식을 사용하여 메소드가 순차적으로 선언되도록 할 수 있다.

Ajax - 비동기식 처리

  • 이름부터 Asynchronous Javascript XML의 줄임말이다. 웹에서 페이지에 접근을 했는데 UI,이미지는 그대로있고 새로운 이미지의 갱신이나 페이지에 필요한 데이터를 로딩할때 데이터를 별도로 가져오는 기술이다.
  • 클라이언트측에서의 API호출-응답에 사용되고 전체페이지를 완전히 갱신하지 않고 일부 데이터만 새롭게 갱신하여 보여줄때 사용된다. 예로들면 브라우저에서 스탑워치를 사용할때나 코인거래소의 차트데이터갱신이 비동기처리에 해당될 것 같다.

동기화를 구현하기 위한 개념

  • Mutex, Semaphoer라는 동기화개념을 바탕으로 프레임워크나 라이브러리에서는 상호배제 도구를 제공한다. semaphore는 mutex에 비하면 완벽한 상호배제를 제공한다고 할 수 없기에 이를 보완해둔 Monitor를 사용하기도 한다.

Mutex

  • 여러 쓰레드를 실행하는 환경에서 자원에 대한 접근에 제한을 강제하기 위한 동기화 메커니즘이다.
  • Boolean타입의 Lock변수를 사용한다. 1개의 공유자원에 대한 접근을 제한한다.
  • 공유자원을 사용중인 쓰레드가 있을때 다른 쓰레드가 공유자원에 접근한다면 Blocking후 대기큐로 보낸다.
  • Lock을 설정한 쓰레드만 Lock을 해제할 수 있다.

Semphore

  • 멀티프로그래밍환경에서 다수의 프로세스나 쓰레드가 n개의 공유자원에 대한 접근을 제한하는 방법으로 사용되는 동기화 기법이다.
  • 세마포어 변수를 통해 wait, signal을 관리한다. 세마포어 변수는 0이상의 정수형 변수를 가진다
  • n개의 공유자원에 대한 접근을 제한할 수 있으며 이를 계수 세마포어라고 한다.
  • 접근가능한 공유자원의 수가 1개일때는 이진 세마포어로 뮤텍스처럼 사용할 수 있다.
  • 큐에 연결된 쓰레드를 깨우는 방식에 따라 강성 세마포어(큐에 연결된 쓰레드를 깨울때 FIFO순서), 약성 세마포어(큐에 연결된 쓰레드를 깨울때 순서를 특별히 명시하지 않음)로 구분된다.
  • Lock을 걸지 않은 쓰레드도 Signal을 보내 Lock을 해제할 수 있다.

Monitor

  • 상호배제를 프로그램으로 구현한것이다. 위의 세마포어 개념의 경우 wait&signal연산 때문에 프로그램으로 구현하기 어렵다. 이러한 단점을 극복하기 위해 모니터가 나왔다.
  • 이진 세마포어를 프로그래밍 언어 수준에서 제공한다.
  • 자바에서 모니터를 사용할때 쓰레드가 자원에 접근하는 과정 - 공유객체에 점유중인 쓰레드는 해당 객체의 Lock을 가지고 있다. 이 객체에 다른 쓰레드가 접근하려고 한다면 외부 모니터 준비큐에서 다른 쓰레드의 진입을 waite한다. 모니터는 Semaphore처럼 signal연산을 보내는것이 아니라 조건 변수를 사용하여 특정조에 대해 대기큐에 signal을 보내서 대기중인 쓰레드를 작업시킨다.

동기화의 구현

  • 동기화를 구현하기 위하여 임계영역과 잠금lock이라는 두가지 개념을 사용한다.
  • 모든 스레드가 공유하는 데이터객체를 사용하는 코드영역을 임계영역으로 지정해놓고 공유데이터객체가 가지고 있는 lock을 획득한 하나의 쓰레드만 임계영역안의 코드를 수행할 수 있게한다. lock을 획득한 쓰레드가 임계영역의 코드를 수행하고 벗어나서 lock을 반납하면 대기하고 있던 다른 쓰레드가 lock을 전달받아 수행하는것이 가능하다.

Java에서 동기화의 구현

  • Monitor라는 도구를 통해 객체에 Lock을 걸어 상호배제Mutex를 통해 동기화를 구현한다.
  • 자바의 모든 인스턴스는 Monitor를 가지고 있고 Monitor를 통해서 Thread동기화를 수행한다.

Synchronized

  • 개발자가 synchronized예약어만 선언해주면 해당 영역은 임계영역으로 지정되어 하나의 스레드만 접근할 수 있다.
  • 쓰레드는 sychronized가 호출된 시점부터 해당영역이 포함된 객체의 lock을 얻어서 작업을 수행하게되고 작업이 끝나면 lock을 반환한다.
  • static메소드의 경우 해당 class에 lock을 걸면서 함수간 lock이 공유되어 동시에 호출되는것을 막는다.

wait() / notify()

  • Lock을 점유하고 있는 쓰레드가 다른 쓰레드에 Lock을 넘겨준 이후에 대기해야한다면 wait()를 사용한다.
  • 대기중인 임의의 쓰레드를 깨울때는 notify()를 사용한다.
  • 대기중인 모든 쓰레드를 깨울때는 notifyAll()을 통해 깨운다. 이 경우 하나의 쓰레드만 Lock을 획득하고 나머지 쓰레드는 대기상태에 들어간다.

개념, 용어정리

  • 임계영역Critical Section : 여러개의 스레드가 공유하는 데이터 블럭을 하나의 스레드만 접근가능하도록 지정한 영역을 말한다.
  • 상호배제Mutual Exclusion/Mutex : 임계구역을 한개의 쓰레드만 사용할 수 있도록 다른 쓰레드의 접근을 막는 기법을 말한다.
  • Semaphore : 상호배제의 한 형태로 상호배제를 수행하기 위해 프로세스의 처리순서를 결정하는 기법을 말한다.
  • 기아상태starvation : 다른 쓰레드에게 우선순위가 밀려 자원을 계속 할당받지 못하는 쓰레드의 상태를 말한다.

'Java' 카테고리의 다른 글

Java Collection  (0) 2024.03.02
Effective Java 정리 #1  (1) 2023.12.10
Servlet서블릿  (0) 2022.05.25
동등성과 동일성의 차이  (0) 2022.05.25
JVM - java버전별 변경점  (0) 2022.05.24