본문 바로가기

회고/세미나

[10분 테크톡] 알렉스, 열음의 멀티스레드와 동기화 In Java 후기

 

기존에 학부 수업이었던 운영체제론에서 들었던 내용이지만 그때는 정확하게 이해 못하기도 했고
또 유사한 내용이 나오니 턱 막히는 것 같아 동영상을 보고 관련 내용을 좀 정리하려고 한다.

그리고 안에서 비유한 내용이 너무 좋아서 내용을 정리해본다.

 

목차

  • 공유자원과 임계영역
  • 경쟁상태
  • 원자성과 가시성
  • 동기화
    • 블로킹
    • 논블로킹
  • 스레드 안전한 객체 설계 방법

 

 

공유자원과 임계영역

공유자원 : 여러 스레드가 동시에 접근할 수 있는 자원

임계영역 : 공유자원들 중 여러 스레드가 동시에 접근했을 때 문제가 생길 수 있는 부분

 

 

경쟁상태

둘 이상의 스레드가 공유자원을 병행적으로 읽거나 쓰는 동작을 할 때 타이밍이나 접근 순서에 따라 실행 결과가 달라지는 상황

아래의 두가지 패턴이 있고 이 경쟁상태를 방지하기 위해서는 원자성과 가시성이라는 것을 보장해야 함

ex) Read - Modify - Write, Check - then - act

 

 

원자성

공유 자원에 대한 작업의 단위가 더이상 쪼갤 수 없는 하나의 연산인 것처럼 동작하는 것

순수함수를 구현한 코드에서 함수를 불러와서 순서대로 진행할 때 시간텀이 생기기 때문에 이를 묶어주는 게 필요

 

 

가시성

예시상황 : 두 개의 스레드가 있는데 첫번째 스레드가 시작되는 건지 쳐다보고 있다가 시작하면 두번째 스레드인 요격 미사일을 발사하여 스레드를 죽임

 

CPU 캐시

CPU가 스레드를 실행할 때 메인 메모리에서 변수 값을 읽어와서 스레드를 실행하게 됨

그런데 CPU간의 거리가 멀어서 CPU 캐시라는 걸 놓고 사용하게 됨

CPU는 이 스레드를 실행할 때 필요한 값을 메인 메모리에서 읽어와서 CPU 캐시에 담아두고 CPU 캐시의 모든 연산을 반영한 다음에 그 값을 메인 메모리에 덮어쓰는 방식으로 동작함

 

무한루프를 돌면서 메인 메모리에 있는 진짜값을 보지 못해서 가시성이라고 함

이는 경쟁 조건 발생을 방지

자바에서는 volatile이라는 키워드를 이용하여 변수를 선언하면 이 변수는 메인 메모리에서만 값을 읽고 쓰기 때문에 CPU 캐시를 사용하지 않는 변수가 됨

 

 

동기화

원자성과 가시성을 챙기는 것을 의미

 

블로킹

특정 스레드가 작업을 수행하는 동안 다른 작업은 진행하지 않고 대기하는 방식

 

모니터

자바에서 동기화를 하기 위한 도구

배타동기는 synchronized, 조건동기는 wait(), notify(), notifyAll()

모니터 알고리즘

 

Synchronized

배타 동기를 선언하는 키워드

연산 결과가 메모리에 써질 때까지 다른 스레드는 대기

순차적으로 임계구역에 들어와서 이미 동기화된 값을 읽어오기 때문에 원자성과 가시성을 동시에 챙길 수 있는 방식

 

데드락 이슈

상의와 하의를 가지고 싸우는 쌍둥이 예시

이런 식으로 교착상태에 빠질 수 있음

 

논블로킹

다른 스레드의 작업여부와 상관없이 자신의 작업을 수행하는 방식

 

CAS (Compare and Set)

자원값과 기댓값이 같으면 기존 자원값을 새로운 값으로 수정하고 true, 다르면 수정하지 않고 false

비교하는 과정에서 원자성을 보장할 수 있음

 

Atomic 타입

동시성을 보장하기 위해서 자바에서 제공하는 Wrapper class

CAS(Compare and set)과 Volatile을 합쳐서 제공함으로써 원자성과 가시성을 보장

Atomic 레퍼런스 설정을 하게 되면 JVM 메모리에서 바로 스레드로 값을 당겨올 수 있음

연산할 때는 compareAndSet()이라는 메소드가 호출됨

이 메소드는 CAS 알고리즘의 메소드라서 원자성이 보장됨

 

 

스레드의 안전한 설계 방법

스레드 안전하다

여러 스레드가 동시에 클래스를 사용하려고 하는 상황에서 클래스 내부의 값을 안정적인 상태를 유지할 수 있는 것

스레드 안전한 객체를 이런 안정성을 갖춘 객체라고 함

!! 공유 변수를 최대한 안 두는 것 !!

공유 변수를 써야 한다면 관리해야 될 포인트를 한 곳에 모아서 한 객체에서 캡슐화하고 그 객체만 관리할 수 있게끔 하자

그리고 동기화 정책을 추가하면 복잡해지니까 문서화를 잘 해두자

 

 

반응형