Process
단순히 실행 중인 프로그램이라 볼 수 있다. 프로그램을 실행하면 OS로부터 실행에 필요한 자원을 할당받아 프로세스가 된다.
Thread?
프로세스라는 작업 공간에 실제로 작업을 처리하는 역할을 한다.
프로세스의 자원을 이용하여 작업을 수행한다.
모든 프로세스에는 최소 하나 이상의 쓰레드가 존재한다.
하나의 쓰레드를 싱글쓰레드, 둘 이상의 쓰레드를 멀티쓰레드라 칭한다.
Multi Tasking
여러 개의 프로세스가 동시에 실행될 수 있는 것을 말한다.
Multi Threading
하나의 프로세스에 여러 쓰레드가 동시에 작업을 수행하는 것이다.
Multi Threading 장점?
•
CPU의 사용률 향상
•
자원을 보다 효율적으로 사용
•
사용자에 대한 응답성 높음
•
작업이 분리되어 코드가 간결
Multi Threading 단점?
•
동기화를 고려해야한다.
•
교착상태에 빠진다면 심각한 문제가 될 수 있다.
•
놀고 있는 쓰레드가 생길 수 있다.
Multi Tasking VS Multi Threading
여기서 궁금증 멀티태스킹, 멀티스레딩 둘다 비슷한데 뭐가 좋을까?
멀티태스킹 | 멀티스레딩 | |
기능 | OS의 기능 | 프로세스의 기능 |
실행 | 여러 프로세스가 동시에 실행 | 단일 프로세스에서 여러 스레드의 실행 |
자원 | 프로세스 간의 리소스 공유 | 스레드 간의 리소스 공유 |
Concurrency? Parallelism?
병렬처리를 공부하면 한번은 듣게 된다. 근데 얘네가 뭘까?
Concurrency | Parallelism |
Single CPU에서도 가능하며 이는 CPU가 작업간 전환을 반복하여 여러 작업을 수행하는 것을 의미한다. Concurrency는 동시에 수행하는 것 처럼 보이지만 진짜 동시 수행은 아니다. | 하위 작업이 개별 CPU를 가지고 병렬로 처리할 수 있어야함을 의미한다. |
java의 동시성 프로그래밍의 진화
•
초기
◦
Runnable, Thread
•
java 5
◦
ExecutorService : 쓰레드 실행과 태스크 제출을 분리
◦
Callable : Runnable의 발전형태, 제네릭 지원, 결과 리턴가능, 예외던지기 가능
◦
Future : 비동기 결과 값을 담기 위한 객체
•
java 7
◦
java.util.concurrent.RecursiveTask 추가 : 포크/조인 구현 지원
•
java 8
◦
CompletableFuture : Future를 조합하는 기능을 추가하면서 동시성 강화
◦
Stream : 내부적으로 병렬처리 가능
•
java 9
◦
리액티브 프로그래밍을 위한 API 지원 : 발행-구독 프로토콜 java.util.concurrent.Flow
동기화?
Multi Thread로 동작하는 프로세스의 경우 여러 Thread가 같은 Process 내의 자원을 공유해서 작업하기 때문에 서로의 작업에 영향을 주게 된다. 만일 Thread A가 작업하던 도중 다른 Thread B에게 제어권이 넘어갔을 때, Thread A가 작업하던 공유 데이터를 Thread B가 임의로 변경하였다면, 다시 Thread A가 제어권을 받을 때 의도하지 않은 결과를 얻을 수 있다. 이러한 일을 방지하기 위하여 다른 Thread에 의해 방해받지 않도록 하는 것이 필요하다. 그래서 도입된 개념이 바로 임계영역(Critical Section), 잠금(Lock) 이다.
공유 데이터를 사용하는 코드 영역을 임계 영역으로 지정하고, 공유한 데이터를 가지고 있는 lock을 획득한 단 하나의 Thread만 이 영역 내의 코드를 수행할 수 있다. Thread가 임계 영역 내의 모든 코드를 수행하고 벗어나서 lock을 반납해야만, 다른 쓰레드가 반납된 lock을 획득하여 임계영역의 코드를 수행 할 수 있게 된다.
최대한 객체 단위의 임계 영역을 줄이는 것이 좋다. 자바에서 3가지의 방법을 지원한다.
Synchronized, Volatile, Atomic Type
처음에는 이걸로 끝낼 생각이 아니었다. 처음에는 process와 Thread의 차이, MultiTasking과 MultiThreading의 차이, 동시성과 병렬성의 차이 이렇게 세분화하고 자바에서의 동시성 프로그래밍 방법의 진화과정을 설명하려 했다. 또한 이렇게 된 원인인 동기화를 문제의 근본적원인을 정리하려고 했다. 하지만 OS레벨까지 나와버려서 정리하기가 힘들었다. 일단은 키워드 상으로 Lock, 세마포어, 모니터가 존재하는 것은 알았다. 이건 차후에 정리하고 일단은 자바의 내용에 좀 더 초점을 맞춰야겠다는 생각을 했다. 그래서 Synchronized, Volatile, Atomic Type의 내용을 pdf에 담에 첨부했다(물론 5주차 때 익명객체에서 왜 final 변수를 사용해야하는가?에 대한 의문을 가지다가 시작했던 정리다.).
이부분은 강의나 다른 책을 통해서 다시 한번 공부해야할 것 같다. 왜냐하면 지금 현재로는 개념이 너무 섞여서 내가 원하는 정답을 찾을 수가 없다….
틀린정리… 뭔가 모르지만 정리가 이상한…. 자바와 OS가 섞여 버렸다..
Multi Threading program에서 빠질 수 없는 것이다. 아까 위에서 언급한 것처럼 이를 고려하여 프로그램을 설계해야한다. 그런데 동기화가 뭘까? 동기화란 무언가에 연동되는 느낌의 단어다. 동기화란 프로세스 또는 스레드들이 수행되는 시점을 조절하여 서로가 알고 있는 정보를 일치하는 것을 의미한다.
이렇듯 동기화는 정보를 일치 시키는 것이고 프로세스 혹은 쓰레드가 동기화 없이 접근하려는 현상을 경쟁 상태라고 한다.
동기화 제공 방법?
기본적으로 동기화는 Lock방법, 세마포어, 모니터가 존재한다. 하나씩 살펴보자
Lock
세마포어
모니터
java의 동기화
java 동기화의 기본 메커니즘은 synchronized 키워드다. 하지만 “synchronized”라는 용어에는 volatile 변수, exclusive locking(명시적 잠금) 및 atomic 변수의 사용도 포함된다(한마디로 짬뽕이다). 자바에선 적절한 동기화를 하지 않으면 안된다. 그래서 3가지 방법이 존재한다. 아래의 방법은 “동기화(정보 일치)”를 위한 작업이다. 다른 말로 풀어보면 Thread Safety를 위한 것이다.
1.
스레드간의 상태 변수 공유 금지
2.
상태 변수를 변경 불가능하게 들기
3.
상태 변수에 접근 할 때마다 동기화를 사용
안전한 코드(A Stateless)
원자성 (Atomicity)
Compound Actions
Locking, 고유잠금 (Intrinsic Locks)