만약 A스레드와 B스레드가 하나의 공유 객체를 바라보면 작업을 한다. 그런데 만약 A스레드 작업 도중에 B스레드의 작업의 영향을 받는 다면 어떻게 될까?? 간단하게 생각해보면 예상치 못한 결과가 나올 것이다.
바로 이때 필요한 것이 스레드 동기화이다.
즉, 진행 중인 작업을 다른 스레드가 간섭하지 못하도록 막는 것을 '스레드 동기화'라고 한다.
그럼 JAVA에서는 동기화 작업을 어떻게 할까???
JAVA에서는 synchronized 키워드와 synchronized 블록으로 스레드의 동기화 작업을 해줄 수 있다.
우선 동기화 작업을 하지 않은 간단한 예제를 보자.
소스를 한번 보자 TaskA와 TaskB 클래스는 각자의 생성자의 매개값으로 ShareInstance를 받았고, run() 메서드를 Overriding 하였고 그 내용으로는 shareWork() 메소드를 불러 메소드 매개 값으로 [TaskA], [TaskB]을 주어 반복문을 통해 10 번식 출력하는 간단한 예제이다.
만약 스레드 동기화라는 개념을 모른다고 봤을 때 실행결과는 당연히 "[TaskA]가 10번, [TaskB] 10번 출력할거야!!" 라고 생각할 수 있다.
결과는 어떨까?? 결과는 예상과 달리 섞여서 출력되었다. 왜 그러는 것일까?? 이유는 간단하다 소스상에서 TaskA, TaskB 클래스는 하나의 공유 객체를 바라보고 작업을 하고 있기 때문에 TaskA가 작업 중에 TaskB가 끼어들 수 있는 것이고, 반대로 TaskB작업 도중에 TaskA가 끼어들 수 있는 것이다.
따라서 우리가 원하는 답을 얻기 위해서는 공유객체에게 "하나의 스레드만 작업할 수 있게 독점권을 줘야 한다." 바로 그것이 Lock이고, "하나의 스레드만 접근 할 수 있는 영역"이 임계 영역(critical section)이다.
그렇다면 이제 우리가 원하는 결과를 얻기 위해 synchronized 와 synchronized block 통해 동기화 작업을 해보자.
소스상 크게 달라진 부분은 없다 하나는 synchronized를 통해 메소드 전체를 임계 영역으로 만들 것이고 다른 하나는 synchronized block 통해 특정 부분만을 임계 영역으로 만든 것이다.
단지 임계영역을 메소드 전체로 해주냐 특정 부분을 해주냐의 차이이다.
p.s 임계영역은 멀티 스레드 프로그램의 성능을 좌우하기에 synchronized block을 통해 임계 영역을 최소화시켜서 작업하는 것이 보다 효율적일 것이다.
이렇게 동기화 작업을 한 후 실행해보면 섞여서 나오지 않고 [TaskA] 10번 [TaskB] 10번 이렇게 순차적으로 찍히는 결과가 나올 것이다.
이상 synchronized, synchronized block, 임계영역(critical section), Lock에 대해서 공부해 봤습니다.
'Java' 카테고리의 다른 글
FileWriter, FileReader 의 사용법 (0) | 2020.03.01 |
---|---|
스레드란?? 그리고 스레드 생성과 실행 (0) | 2020.02.15 |