에볼루션 바카라 무료와 마찬가지로 코루틴도 비동기로 동작하기 때문에 공유 자원 관리에 대한 고민이 필요하다. 다시 말하면 공유 자원 관리가 코루틴만의 특별한 요소가 아니라는 것이다.
JVM 에볼루션 바카라 무료 공유 자원
JVM 메모리 구조를 기준으로 에볼루션 바카라 무료가 공유하는 자원은 메서드 영역(Method Area)과 힙 영역(Heap Area)이다. 메서드 영역은 클래스 정의, 메서드 정보, 정적 변수 등이 저장된다. 힙 영역에는 객체와 배열이 저장되고 가비지 컬렉터에 의해 관리된다. 나머지 영역은 에볼루션 바카라 무료마다 독립적으로 존재한다.
비동기 상황에서 공유 자원의 문제점
두 에볼루션 바카라 무료가 함께 공유 자원을 사용할 때 원자성이 보장되지 않으면 문제가 발생할 수 있다.원자성이 뭔지 몰라도 상관없다. 일단 다음 코드를 보고 실행 결과를 예측해 보자.
아마 공유 자원에 대한 문제점을 경험하지 못한 사람이라면 number의 값이 2000이라고 생각할 수 있다. 물론 2000인 경우도 있지만 2000보다 작은 수일 경우가 더 많을 것이다.
실행 결과는 다음과 같다. (알다시피 매번 바뀐다.)
Final counter value: 1587
원자성이 뭔데?
원자성이 보장되지 않으면 발생할 수 있는 문제라고 했는데 그럼 원자성 뭘까? 원자성은 더 이상 쪼개질 수 없는 성질을 말한다. 프로그래밍에서는 어떤 작업을 쪼갤 수 없다고 생각하면 된다. 따라서원자성을 보장한다는 것은 작업(연산)이 중간에 끊기지 않고 모두 완료되거나 아니면아예실행되지 않아야 함을 의미한다.부분적인 실행과 같은 중간 상태는 존재하지 않는다.number가 증가되는 연산은 다음과 같이 나눌 수 있다.
1. 현재 number 값을 읽는다. 2. number 값을 1 증가시킨다. 3. 증가된 값을 number에 반영한다.
이 과정이 원자성을 가지지 않으면 연산 과정에서 데이터 경합이 발생한다. 예를 들어, 두 에볼루션 바카라 무료가 거의 동시에 number의 값을 읽으면 같은 값을 읽게 된다. 그 후 각 에볼루션 바카라 무료가 1 증가시킨 후 그 값을 다시 number에 쓸 수 있다. 그러면 number의 초깃값이 0이었다면 증가된 값은 2가 아니라 1이 된다. 이 과정을 그림으로 나타내면 다음과 같다.
하나의 에볼루션 바카라 무료가 값을 1 증가시킨 후 그 값을 다시 number에 쓰기 전에 다른 에볼루션 바카라 무료가 number의 값을 읽어서 발생한 문제다. 원자성을 가졌다면 위 3단계가 하나의 작업으로 완료 후에 다른 작업이 시작되어야 한다. 하지만 이 경우에는 작업 도중에 다른 에볼루션 바카라 무료가 이전 작업에 끼어들었다. 이것은 작업이 완료되지 않은 부분적인 실행 상태에서 방해를 받은 것이다.원자성이 보장되지 않은 것이다.
그러면 원자성을 보장할 수 있는 방법은 무엇이 있을까?
동기화블록,잠금,조건 변수,원자 변수 등이 있다. 모두 근본적으로는하나의 작업이 완료된 후에 다음 작업이 시작되도록 제어하는 것이다. 이것은 에볼루션 바카라 무료에서도다를 게 없다.
에볼루션 바카라 무료 공유 자원 문제
코루틴 공유 자원 관리라는 제목을 적어놓고 왜 에볼루션 바카라 무료 관한 이야기만 했을까? 스레드 내에서 동작하는 코루틴을 이해하려면 에볼루션 바카라 무료 관한 이해는 필수다. 거기에 더해 비동기 선배인 스레드가 겪어온 길이 코루틴에 귀감이 되기 때문이다. 에볼루션 바카라 무료서 이미 원자성 보장을 위한 대책을 내놓은 것이 코루틴에도 유효한 부분이 있다는 말이다. 정말인지 코루틴에서 발생하는 공유 자원 문제를 살펴보자.
다음 코드의 실행 결과는 무엇일까? 지금까지 다룬 에볼루션 바카라 무료 내용을 잘 숙지했다면 추측해 볼 수 있다.
실행 결과는 다음과 같다.
Final counter value = 1000
실행 결과 number가 1000 이하가 아니라 1000인 이유가 무엇일까? 여태까지 다룬 내용에서는 에볼루션 바카라 무료 자체의 실행 순서를 집중해서 살펴봤다. 하지만 내부에서 반복되는 경우는 깊게 고민한 적이 없었다. 그래도 학습한 내용을 잘 조합해 보면 그럴듯한 추측을 할 수 있을 것이다.
위 코드는 coroutineScope로 새로운 코루틴 스코프를 만들고 내부에서 launch로 코루틴을 실행하고 있다. 그리고 1000번 반복하며 launch를 통해 코루틴을 실행한다. 즉 1000개의 코루틴을 생성한다. 그러면 에볼루션 바카라 무료서 공유 자원 관리 시 겪은 문제점에 대해 고려해 볼 수 있다.
1. 데이터 경합이 발생했는가? 2. 원자성이 보장되는가?
일단 결과가 1000이 나왔으니 문제가 없다는 뜻이다. 에볼루션 바카라 무료서 데이터 경합이 발생한 경우를 돌이켜 보면 두 개의 스레드가 같은 자원에 접근하는 것이 문제였다. 현재 코루틴은 어떤가? 1000개의 코루틴이 같은 자원을 두고 경쟁을 하는가? 당연히 아니다.
결국 데이터 경합은 코루틴의 문제가 아니라 에볼루션 바카라 무료의 문제다. 앞선 예제의 에볼루션 바카라 무료와 코루틴의 구조를 그려보면 다음과 같다.
launch는 runBlocking의 컨텍스트를 상속받아 실행된다. 따라서 실행되는 스레드는 메인 스레드다. 메인 에볼루션 바카라 무료서 실행된 코루틴은 같은 에볼루션 바카라 무료서 쭉 실행된다. 그리고 해당 에볼루션 바카라 무료서 실행되는 코루틴은 순차적으로 실행된다. 결국 데이터 경합이 발생하지 않는 것이다. 확인해 보고 싶다면 launch 블록 내에
println("thread ${Thread.currentThread().name} counter = $number")와 같은 출력을 해보면 된다.
에볼루션 바카라 무료에서 데이터 경합
그러면 코루틴에서는 공유 자원 관리가 필요하지 않나?...라고 생각하진 않을 것이라 믿는다. 코루틴은 특정한 에볼루션 바카라 무료 종속되지 않는다고 했다. 그럼 방금 전 메인 에볼루션 바카라 무료서는 왜 종속되었을까? 메인 스레드, Dispatchers.Unconfined와 같은 디스패처는 예외다.
그렇다면 Dispatchers.IO,Dispatchers.Default와 같은 다중 에볼루션 바카라 무료 풀에서 코루틴을 실행하는 디스패처를 사용하면 데이터 경합이 발생한다는 말이 된다. 이것을 확인하기 위해서 앞선 예제를 살짝 수정해 보자.
launch에 디스패처를 지정했다. 이제 메인 에볼루션 바카라 무료서 실행되지 않고 에볼루션 바카라 무료 종속되지도 않는 상태가 되었다.
1000개의 코루틴이 생성되었고 특정 에볼루션 바카라 무료 종속되지 않았다. 결국 데이터 경합이 발생하여 원자성이 보장되지 않아 최종 값이 995가 되었다.
에볼루션 바카라 무료의 상호 배제
그러면 원자성을 보장하려면 어떻게 해야 할까? 앞서 말했듯이 방법은동기화 블록, 잠금, 조건 변수, 원자 변수 등이 있다. 이러한 방식의 목적은 하나의 작업 단위가 실행될 때 다른 에볼루션 바카라 무료가 끼어들지 못하게 막는 것이다.(원자 변수는 조금 다른 방식이다.) 공유 자원에 접근을 제한하여 어떤 작업이 절대로 동시에 수행되지 않도록 하는 것이다. 그리고 그러한 공유 자원에 접근하는 작업 영역을 임계 구역(critical section)이라고 한다. 코드로 생각하면 공유 자원에 접근하는 코드 블록이다. 해당 코드 블록은 단 하나의 에볼루션 바카라 무료 또는 코루틴이 실행할 수 있다.
동기화 블록, 잠금, 조건 변수와 같이 공유 자원에 접근을 제한(blocking)하는 방식을 상호 배제(Mutual Exclusion)이라고 한다. 보통 줄여서 뮤텍스(Mutex)라고 부른다. 그리고 뮤텍스는 이런 상호 배제를 구현하는 하나의 방식이기도 하다.
에볼루션 바카라 무료도 뮤텍스를 지원한다. 앞선 데이터 경합이 발생한 예제에 적용하면 다음과 같다.