Thread 쓰레드
Process & Thread 프로세스와 쓰레드
- 프로세스
- 실행중인 프로그램, 자원 (resources) 과 쓰레드로 구성
- 쓰레드
- 프로세스 내에서 실제 작업을 수행
- 모든 프로세스는 최소한 하나의 쓰레드를 가지고 있다.
💡 프로세스 : 쓰레드 = 공장 : 일꾼
멀티 쓰레드
- 대부분의 프로그램이 멀티 쓰레드로 작성
- 멀티 쓰레드의 장점
- 시스템 자원을 효율적으로 사용
- 사용자에 대한 응답성이 향상
- 작업이 분리되어 코드가 간결해진다.
- 멀티 쓰레드의 단점
- 동기화 (synchronization) 에 주의
- 교착 상태 (dead-lock) 가 발생하지 않도록 주의
- 각 쓰레드가 효율적으로 고르게 실행될 수 있게 해야 한다.
쓰레드 구현
-
Thread 클래스 상속
- Java 는 단일 상속만 허용하기 때문에 인터페이스로 구현하는게 낫다.
-
Runnable 인터페이스 구현
- 추상 메서드
run()
구현 (main()
메서드 사용과 동일)
class MyThread implements Runnable {
public void run() {
}
}
쓰레드 실행 start()
ThreadEx1_1 t1 = new ThreadEx1_1();
ThreadEx1_1 t2 = new ThreadEx1_1();
t1.start();
t2.start();
- 쓰레드를 생성한 후에 start() 를 호출해야 쓰레드가 작업을 시작
- start() - 실행 가능한 상태로 전환
- 실행 순서는 OS 스케줄러가 결정
- 코드 순서가 쓰레드 실행 순서와 다를 수 있다.
start()와 run()
class ThreadTest {
public static void main(String args[]) {
MyThread t1 = new MyThread();
t1.start();
}
}
- 쓰레드 생성
- 쓰레드 실행
class MyThread extends Thread {
public void run() {
}
}
main 쓰레드
- main 메서드의 코드를 수행하는 쓰레드
- 쓰레드는 ‘사용자 쓰레드’와 ‘데몬 쓰레드’ (보조 쓰레드) 두 종류가 있다.
💡 실행 중인 사용자 쓰레드가 하나도 없을 때 프로그램은 종료 된다.
쓰레드의 I/O 블락킹 (blocking)
- 입출력시 작업 중단
- I/O 작업 중단 되는 동안 멀티 쓰레드로 다른 작업 진행
Thread priority 쓰레드 우선순위
- 작업의 중요도에 따라 쓰레드의 우선순위를 다르게 하여 특정 쓰레드가 더 많은 작업시간을 갖게 할 수 있다. (희망 사항)
void setPriority(int newPriority)
int getPriority()
public static final int MAX_PRIORITY = 10
public static final int MIN_PRIORITY = 1
public static final int NORM_PRIORITY = 5
쓰레드 그룹
- 서로 관련된 쓰레드 그룹으로 묶어서 다루기 위한 것
- 모든 쓰레드는 반드시 하나의 쓰레드 그룹에 포함되어 있어야 한다.
- 쓰레드 그룹을 지정하지 않고 생성한 쓰레드는 main 쓰레드 그룹에 속한다.
daemon thread 데몬 쓰레드
- 일반 쓰레드의 작업을 돕는 보조적인 역할 수행
- 일반 쓰레드가 모두 종료되면 자동 종료
- 가비지 컬렉터, 자동저장, 화면 자동갱신 등에 사용
- 무한 루프와 조건문을 이용
쓰레드의 상태
상태 | 설명 |
---|
NEW | 쓰레드가 생성되고 아직 start() 가 호출되지 않은 상태 |
RUNNABLE | 실행 중 또는 실행 가능한 상태 |
BLOCKED | 동기화 블럭에 의해서 일시정지된 상태 |
WAITING, TIMED_WAITING | 실행 가능하지 않은 일시정지 상태 |
TERMINATED | 쓰레드의 작업이 종료된 상태 |
쓰레드 메서드
sleep()
interrupt()
- 대기상태 (WAITING) 인 쓰레드를 실행 대기 상태 (RUNNABLE) 로 만든다.
suspend(), resume(), stop()
- 쓰레드의 실행을 일시정지, 재개, 완전정지
- 교착 상태에 빠지기 쉬워서 deprecated
join()
- 지정된 시간동안 특정 쓰레드가 작업하는 것을 기다린다.
yield()
- 남은 시간을 다음 쓰레드에게 양보
- 자신 현재 쓰레드는 실행 대기
Synchronization 쓰레드의 동기화
- 멀티 쓰레드 프로세스에서는 다른 쓰레드의 작업에 영향을 미칠 수 있다.
- 진행중인 작업이 다른 쓰레드에게 간섭받지 않게 하려면 ‘동기화’ 필요
💡 쓰레드의 동기화 - 한 쓰레드가 진행중인 작업을 다른 쓰레드가 간섭하지 못하게 막는 것
wait() notify()
- 동기화의 효율을 높이기 위해 사용
- 동기화 블록 내에서만 사용
- wait()
- 객체의 lock을 풀고 쓰레드를 waiting pool 에 넣는다.
- notify()
- waiting pool 에서 대기중인 쓰레드 중의 하나를 깨운다.
- notifyAll()
- waiting pool 에서 대기중인 모든 쓰레드를 깨운다.