자바 메모리 구조
- 메소드 영역 : 프로그램을 실행하는데 필요한 공통 데이터를 관리하는 영역으로 프로그램의 모든 영역에서 공유한다.
- 클래스 정보 - 클래스 실행 코드, 필드, 메소드, 생성자 코드 등...
- static 영역 - static 변수를 보관한다.
- 런타임 상수 풀 - 프로그램을 실행하는데 필요한 공통 리터럴 상수를 보관한다.
- 스택 영역 : 자바 실행 시(각 스레드 별로) 하나의 실행 스택이 생성되며 각 스택 프레임은 지역 변수, 중간 연산 결과, 메소드 호출 정보 정보 등을 포함한다.
- 스택 프레임 - 스택 영역 안에 쌓이는 네모 박스가 하나의 스택 프레임으로 메소드 호출 시마다 하나의 스택 프레임이 쌓이고 메소드 종료 시 해당 스택 프레임이 제거된다.
- 스레드 수 만큼 스택 영역이 생성된다.
- 힙 영역 : 객체와 배열이 생성되는 영역으로 GC가 이루어지는 주요 영역이다.
스레드
- 자바에서는 스레드도 객체로 다룬다.
- start() : 스레드를 실행하는 메소드
- run()이 아닌 start()를 호출해야 run() 코드가 실행된다.
- 스레드에 스택 영역을 할당하면서 스레드를 시작하는 특별한 메소드의 역할
- run()이 아닌 start()를 호출해줘야 별도의 스레드의 스택 영역이 할당되고 기능을 수행할 수 있다.
- run() : start()를 호출하면 스레드에서 정의한 run() 코드가 실행된다.
- 프로세스가 작동하려면 최소 하나의 스레드가 있어야한다.
- 자바는 실행 시점에 main 스레드를 만들고 프로그램의 시작점인 main() 메소드를 실행한다.
- 스레드 객체를 생성하고 start()를 호출할 때 스택 영역을 할당 받고 스레드가 작동한다
- 메소드 실행 시 스택 영역안에 스택 프레임이 쌓인다.
- main()에서 스레드 객체.start()를 하더라도 main 스레드가 run()을 호출하는 것이 아닌 별도의 스레드에게 스레드 실행을 지시할 뿐이고 별도의 스레드에서 run()이 호출된다.
만약 start()가 아닌 run()을 main()에서 호출하면 별도의 스레드에서 run()이 호출되는 것이 아닌 main 스레드에서 호출이 되버린다.
- 스레드의 이름을 별도로 부여하지 않으면 자바에서 자동으로 임의의 이름을 부여한다.
- 멀티 스레드 - 스레드 간 실행 순서와 실행 기간을 보장하지 않는다.
- 스레드는 동시에 실행되기 때문에 스레드 간 실행 순서는 얼마든지 달라질 수 있다.
- 스레드의 종류
- 사용자 스레드(non - daemon thread)
- 프로그램의 주요 작업을 수행한다.
- 작업이 완료될 때까지 실행된다.
- 모든 사용자 스레드가 종료되면 JVM이 종료된다.
- 데몬 스레드
- 백그라운드에서 보조적인 작업을 수행한다.
- 모든 사용자 스레드가 종료되면 데몬 스레드는 자동으로 종료된다.
- JVM은 데몬 스레드의 실행 완료를 기다리지 않기에 데몬 스레드가 아닌 모든 사용자 스레드가 종료되면 자바 프로그램도 종료한다.
- 사용자 스레드(non - daemon thread)
- 데몬 스레드는 setDaemon(true)로 설정할 수 있다.
- 데몬 스레드의 여부는 start() 실행 전에 결정해야 하며 이후에는 변경할 수 없다.
- run() 메소드 내부에서 체크 예외는 밖으로 throw 할 수 없어서 무조건 내부에서 try-catch로 잡아서 처리해야 한다.
- 스레드를 생성하는 방법
- Thread 클래스를 상속 받는 방법
- Runnable 인터페이스를 구현하는 방법
- Thread 생성자의 인자로 Runnable 구현 객체를 넘겨줘야 한다.
- Thread 상속 vs Runnable 구현
- ★스레드를 사용할 때 Thread를 상속 받는 방법보다 Runnable 인터페이스를 구현하는 방식을 사용해라★
- 자바에서는 단일 상속만 허용하기 때문에 Thread를 상속받으면 다른 클래스를 상속받을 수 없기 때문
- Thread 클래스 상속 - 간단한 구현이 가능하지만 타 클래스로부터의 상속이 제한되고, 유연성이 떨어진다.
- Runnable 인터페이스 구현 - 상속이 자유롭고 스레드와 실행할 작업을 분리해 코드의 가독성을 높일 수 있으며 여러 스레드가 동일한 Runnable 객체를 공유함으로 자원 관리를 효율적으로 할 수 있다.
- ★스레드를 사용할 때 Thread를 상속 받는 방법보다 Runnable 인터페이스를 구현하는 방식을 사용해라★
- 특정 클래스 안에서만 스레드를 사용하는 경우 중첩 클래스로 Runnable 구현 클래스를 만드는 것이 좋다.
- 익명 클래스를 사용해서 Runnable 구현 객체를 만들 수도 있다.
- 람다를 사용해서 메소드 코드 조각을 전달할 수 있다.
출처 : [인프런 김영한 실전 자바 - 고급편]
김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성 강의 | 김영한 - 인프런
김영한 | 멀티스레드와 동시성을 기초부터 실무 레벨까지 깊이있게 학습합니다., 국내 개발 분야 누적 수강생 1위, 제대로 만든 김영한의 실전 자바[사진][임베딩 영상]단순히 자바 문법을 안다?
www.inflearn.com
'Java > [인프런 김영한 실전 자바 - 고급편]' 카테고리의 다른 글
[인프런 김영한 실전 자바 - 고급편] concurrent.Lock (0) | 2024.08.02 |
---|---|
[인프런 김영한 실전 자바 - 고급편] 동기화 - synchronized (0) | 2024.08.02 |
[인프런 김영한 실전 자바 - 고급편] 메모리 가시성 (0) | 2024.08.02 |
[인프런 김영한 실전 자바 - 고급편] 스레드 제어와 생명 주기 1, 2 (1) | 2024.08.02 |
[인프런 김영한 실전 자바 - 고급편] 프로세스와 스레드 소개 (2) | 2024.07.30 |