스레드에 대한 자바의 정의
프로그램을 실행하는 스레드 단위. JVM은 한 애플리케이션에서 여러 Excution을 동시에 이루어지도록 한다.
(A thread is a thread of execution in a program. The Java virtual machine allows an application to have multiple threads of execution running concurrently.)
- 스레드는 간접적으로 동시성을 구현하기 위한 도구
- 스레드는
run 을 통해 실행되며 작업을 정상적으로 마쳤을 때 (더 이상 실행시킬 코드가 남아있지 않을 때), 예외가 발생했을 때, join (스레드가 완료될 때까지 기다리는 메서드) 명령어를 쓸 때 등의 상황에서 중단될 수 있다.
- Thread는 구분자(identifier)와 이름(name)을 갖는다.
- id는 직접 지정이 불가능
- 이름은 직접 지정이 가능하며 하지 않을 경우 자동 생성
예시 코드
Thread t1 = new Thread();
System.out.println("thread id : " + t1.getId());
System.out.println("thread name : " + t1.getName());
Thread t2 = new Thread();
System.out.println("thread id : " + t2.getId());
System.out.println("thread name : " + t2.getName());
실행 결과
thread id : 20
thread name : Thread-0
thread id : 21
thread name : Thread-1
OS상의 Thread와의 차이
- OS상의 스레드와 1:1로 매핑되는 스레드
- OS Scheduler가 관리
Virtual Thread
- OS상의 스레드와 N:M으로 매핑되는 Java에서 만든 가상의 스레드
- JVM의 Scheduler가 관리
- Default는 Platform Thread
- Virtual Thread는 JVM 21 부터 사용 가능 (19부터 쓸 수 있었다고는 하는데...)
- I/O 대기(HTTP/DB/File)가 대부분이면 가상스레드를 사용 (생산 및 유지 비용이 적음)
- CPU 계산, OS의 스레드 기능 등이 대부분이면 플랫폼 스레드를 사용
Thread 에서의 작업
- Thread에서의 작업은 Runnable과 Callable로 구현된다.
- Runnable과 Callable은 모두 인터페이스며 이를 통해 간접적으로 코드베이스를 전달한다.
- Runnable은 반환값이 존재하지 않는 실행을 대변한다.
- Callable은 결과를 반환하거나 그렇게 할 수 없을 경우 예외를 던진다.
- start를 하게 되면 Thread에서 Runnable / Callable의 run 메서드를 실행해준다.
- Thread의 Context는 ThreadLocal 변수에 보관된다. (라고 하네요)
Concurrency
Thread는 하나의 애플리케이션 내 여러 작업을 비동기적으로 실행하기 위해 존재한다.따라서 동시성을 제어하는 것이 중요한 이슈 중 하나이다.
수명 (LifeCycle)
- NEW : 객체가 생성은 됨, 스레드가 시작된 것은 아님
- RUNNABLE : 실행 (스케줄링 대기 중일 수도 있음)
- start 메서드로 실행
- BLOCKED / WAITING / TIMED WAITING : 대기중인 상태
- syncronized, wait, sleep, join ...
- TERMINATED : 스레드가 종료됨 (run에 있는 코드베이스를 모두 실행)
동기화
- volite(스레드에 의존성이 낮은 변수), synchronized(간단한 상호배제 기능 포함), Lock/Condition, 원자 클래스(Atomic), 그 밖의 동시성을 제어하는 도구들 (BlockingQueue, Semaphore) 등을 활용할 수 있다.