Process 와 Thread 에 대해 공부했던 내용을
복습하는 하려고 한다.
실행 중인 프로그램을 의미
TEXT( CODE )
DATA
HEAP
낮은 주소
에서 높은 주소
로 할당 된다.STACK
메모리가 어디에 할당 되는지 구분을 하기 위해서 정한 개념
낮은 주소에는 정적 리소스 들이 할당 되고, 높은 주소에는 동적 리소스가 할당이 된다.
높은 주소라고 데이터 접근에 이점이 있는 것이 아니며,
메모리 관리와 프로그램 구조 때문에 쉽게 구분하기 위해서 사용한다.
OS 로 부터 할당 받은 자원을 사용하는 실행단위
스레드는 하나의 프로세스 내에서 여러 작업을 동시에 수행하기 위해 사용한다.
각 스레드는 독립적인 실행 경로를 가지며, 서로 다른 함수나 변수를 사용하여 다른 작업을 수행할 수 있다. 스레드 간의 상호 간섭이나 충돌을 방지하기 위해, 실행 중인 스레드는 고유해야한다.
이를 위해 스레드는 독립적인 스택을 가지며, Thread 의 스택은 공유 되지 않는다.
Thread 가 두 가지 이상의 일을 처리하는 것
I/O 블록 처리는 CPU 가 작업을 수행하지 않는다.
그렇다면 Thread 를 새로 생성해서 사용하는 것인가 궁금했다.
답은 주로 비동기적인 방식으로 작업을 처리하여 다른 Process 에게 넘긴다고 한다.
즉, I/O 작업이 수행되는 동안 CPU 는 다른 Thread 에게 일을 할당을 한다.,
A 라는 Thread 에 ‘a’, b’ 라는 일이 있고
B 라는 Thread 에 ‘c’ 라는 일을 할당하여 수행 중 일 때,
before
A : ‘a’, ‘b’
B : ‘c’
B Thread 가 I/O Block 에 빠지게 되면 B가 하고 있던 ‘c’라는 일을
A 가 할당하게 되어 다음과 같은 형태가 된다.
AFTER
A : ‘a’, ‘b’, ‘c’
B : I/O
서로 다른 프로세스가 서로 다른 일을 동시에 수행하는 것
public static void main(String[] args) {
// 현재 PC 코어 갯수 구하기
int coreCnt = Runtime.getRuntime().availableProcessors();
System.out.println("CORE ( PROCESS ) : "+coreCnt);
List<Integer> list = new ArrayList<>();
for(int i = 0; i < coreCnt; i++) {
list.add(i);
}
// START TIME
long startTime = System.currentTimeMillis();
long sum = list.parallelStream()
.mapToLong(i -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return i;
})
.sum();
long endTime = System.currentTimeMillis();
System.out.println("RUNNING TIME: " + (endTime - startTime) + "ms");
System.out.println("RESULT : " + sum);
}
Description
CORE ( PROCESS ) : 16
RUNNING TIME: 523ms
RESULT : 120
현재 동작하고 있는 코어의 개수가 16 이고, 그 수만큼 배열에 추가한다.
배열을 순회할 때마다 0.5 초 씩 소요가 됨으로 16 * 0.5 = 8초 정도 소요 될 거라고 예상 하지만
Thread 가 하나씩 할당되어 총 16 쓰레드가 동작하여 병렬처리를 수행하기 때문에
0.5 초 정도 걸렸다.
public class Concurrency {
public static void main(String[] args) {
// 현재 PC 코어 갯수 구하기
int coreCnt = Runtime.getRuntime().availableProcessors();
System.out.println("CORE ( PROCESS ) : "+coreCnt);
System.out.println("PROGRAM COUNT : "+coreCnt+1);
List<Integer> list = new ArrayList<>();
for(int i = 0; i < coreCnt+1; i++) {
list.add(i);
}
// START TIME
long startTime = System.currentTimeMillis();
long sum = list.parallelStream()
.mapToLong(i -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return i;
})
.sum();
long endTime = System.currentTimeMillis();
System.out.println("RUNNING TIME: " + (endTime - startTime) + "ms");
System.out.println("RESULT : " + sum);
}
Description
CORE ( PROCESS ) : 16
PROGRAM COUNT : 161
RUNNING TIME: 1020ms
RESULT : 136
현재 동작하고 있는 코어의 개수가 16 이며, 코어 개수 보다 많은 일을 처리한다.
16개의 코어 중에서 1개의 코어는 2개의 일을 해야 하며
동시성이 일어난다.
16개에서 17개로 하나밖에 차이가 나지 않지만,
16 개 일 때는 코어 하나에 하나의 일이 할당 되어 전부 동시에 일을 처리할 수 있지만
17 개 일 때는 하나의 코어가 2개의 일을 할당 받아 동시성이 일어나서
0.5초 가 실행되는 동안 나머지 일에서도 0.5 초 기다리는 로직이 발생하여
발생하는 시간이 약 1초가 걸리는 것을 확인 할 수 있다.