JAVA - 쓰레드의 메모리 구성
- JAVA
- 2018. 3. 31. 15:33
이번엔 쓰레드의 메모리구성에 대해 알아보자.
쓰레드 생성 포스팅에서 쓰레드가 생성되면 가상머신은
쓰레드의 실행을 위한 별도의 메모리 공간을 할당한다고 했다.
그렇다면 이러한 별도의 메모리공간은
정확히 무엇을 의미하는걸까?
쓰레드의 가장 큰 역할은 별도의 실행흐름 형성이다. 그리고 별도의
실행흐름은 메소드의 호출을 통해서 형성된다.
즉 처음에 run메소드가 호출되고 run메소드 내에서 또다른 메소드를
호출하면서 main메소드와는 다른 흐름을 형성한다.
이렇듯 main 메소드와는 전혀 다른 실행흐름을 형성하기 위해서는
별도의 스택이 쓰레드에게 할당되어야 한다.
따라서 main 쓰레드 이외에 두 개의 쓰레드가 추가로 생성되면
가상 머신은 아래의 형태로 메모리를 구성한다.
위 그림에서 처럼 모든 쓰레드는 자신의 스택을 할당 받는다.
그러나 힙과 메소드 영역은 모든 쓰레드가 공유한다.
여기서 특히 힙이 공유됨에 주목하자. 힙 영역이 공유된다는 것은
모든 쓰레드가 동일한 힙 영역에 접근이 가능함을 의미하는 것이고
이는 다음과 같은 일이 가능함을 의미한다.
"A쓰레드가 만든 인스턴스의 참조값(주소값)만 알면
B쓰레드도 A쓰레드가 만든 인스턴스에 접근 가능"
그래서 쓰레드 사이에 데이터를 주고받아야 할 때에는
(쓰레드간의 통신이 필요할 때) 힙 영역을 활용한다
그럼 둘 이상의 쓰레드가 힙에 할당된 특정 메모리 영역에
함께 접근하는 예를 보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | package com.jsp.ex; class Sum{ int num; public Sum() { num = 0; } public void addNum(int n) {num +=n;} public int getNum() { return num;} } class AdderThread extends Thread{ Sum sumInst; int start, end; public AdderThread(Sum sum, int s, int e){ sumInst = sum; start = s; end = e; } public void run(){ for(int i = start; i<=end; i++) sumInst.addNum(i); } } class test2{ public static void main(String[] args){ Sum s=new Sum(); AdderThread at1 = new AdderThread(s,1,50); AdderThread at2 = new AdderThread(s,51,100); at1.start(); at2.start(); try{ at1.join(); at2.join(); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println("1~100까지의 합 :" +s.getNum()); } } | cs |
25line 에서 생성한 인스턴스의 참조값을
26,27line에서 생성하는 쓰레드 인스턴스에 생성자를
통해서 전달하고 있다. 따라서 두 개의 쓰레드는 25line에서
생성한 인스턴스에 접근이 가능하다.
29~30line에서는 start메소드 호출을 통해서 두 개의 쓰레드가 실행되었다.
이로써 두 쓰레드는 run메소드를 실행하면서 25line에서 생성한
인스턴스에 접근을 한다. 실제 접근은 20line에서 일어난다.
'JAVA' 카테고리의 다른 글
JAVA - split() 사용하기 (0) | 2018.04.25 |
---|---|
JAVA - 동기화 (0) | 2018.04.19 |
JAVA - 쓰레드의 라이프 싸이클(Life Cycle) (0) | 2018.03.31 |
JAVA - 쓰레드의 스케줄링과 쓰레드의 우선순위 컨트롤 (2) | 2018.03.31 |
JAVA - 쓰레드를 생성하는 두 번째 방법 (0) | 2018.03.16 |