출처 - Java의 정석 기초편 (남궁 성)
1. 프로세스 : 쓰레드 = 공장 : 일꾼
- 프로세스(process): 실행 중인 프로그램(program), 자원(resources)과 쓰레드로 구성(프로그램→실행→자원(메모리) 할당→프로세스)
- 쓰레드(thread): 프로세스 내에서 실제 작업을 수행, 모든 프로세스는 최소한 하나의 쓰레드가 존재
- 싱글쓰레드: 자원 + 쓰레드
- 멀티쓰레드: 자원 + 쓰레드 + 쓰레드 + ...
2. 멀티쓰레딩 장단점
- 장점: CPU 사용률 향상, 자원의 효율적 사용, 사용자 응답성 향상, 작업 분리→코드 간결
- 단점: 자원 공유→동기화, 교착상태(dead-lock), 각 쓰레드 효율적으로 실행되어야 함(기아)
- 문맥 전환(context switching): 프로세스 또는 쓰레드 간 작업 전환
3. 쓰레드 구현과 실행
- 구현: 두 가지 방법 중 선택하여 run()의 몸통{} 만들기
- Thread클래스 상속: 자바 단일 상속
- Runnable인터페이스 구현: 다른 클래스 상속 가능→better
// Thread클래스 상속
class MyThread extends Thread {
public void run() {
for(int i=0; i<5; i++) {
System.out.println(getName()); // 쓰레드 이름 반환
}
} // Thread클래스의 run() 오버라이딩
}
// Runnable인터페이스 구현
class MyThread implements Runnable {
public void run() {
for(int i=0; i<5; i++) {
System.out.println(Thread.currentThread().getName()); // 현재 실행중인 쓰레드 참조 반환
}
} // Runnable인터페이스의 run() 구현
}
4. start()
- 쓰레드 생성→start() 호출→실행 대기→실행
- OS 스케줄러가 쓰레드 실행순서 결정: 쓰레드 OS에 종속적
- start() 호출: 새로운 호출스택(call stack) 생성해 run() 호출→main메서드와 서로 독립적 작업 수행
ThreadEx1_1 t1 = new ThreadEx1_1(); // Thread 자손 클래스 인스턴스 생성
Runnable r = new RhreadEx1_2(); // Runnable을 구현한 클래스
Thread t2 = new Thread(r);
Thread t2 = new Thread(new ThreadEx_1_2()); // 한 줄로
t1.start(); // 먼저 start 했다고 먼저 실행되는 것 아님 → OS 스케줄러가 결정
t2.start(); // start() 호출 했다고 즉시 실행 아님 → 실행 대기
5. main쓰레드
- main메서드의 코드를 수행하는 쓰레드
- 쓰레드 종류: 사용자 쓰레드(main쓰레드), 데몬 쓰레드(보조 쓰레드)
- 프로그램은 실행 중인 사용자 쓰레드가 하나도 없을 때 종료
6. 쓰레드 I/O블락킹(blocking)
- 입력(Input), 출력(Output)시 작업 중단되는 것
- 사용자 데이터 입력, 네트워크로 파일 송수신, 프린터 출력 등
- 멀티쓰레드 프로세스 처리시 사용자 입력 기다리는 동안 다른 쓰레드 작업 가능→작업 효율적
7. 쓰레드 우선순위
- 범위: 1~10(기본값 5)
- 작업 중요도에 따라 쓰레드 우선순위를 다르게 지정→특정 쓰레드가 더 많은 작업시간 갖게 할 수 있음
- 우선 순위는 쓰레드가 실행된 이후에도 변경 가능
- 불확실성: 희망사항에 불과
void setPriority(int newPriority) // 쓰레드 우선순위를 지정한 값으로 변경
int getPriority() // 쓰레드 우선순위 반환
8. 쓰레드 그룹
- 서로 관련된 쓰레드를 그룹으로 다루기 위함
- 모든 쓰레드는 반드시 하나의 쓰레드 그룹에 포함
- 쓰레드 그룹을 지정하지 않고 생성한 쓰레드는 main쓰레드 그룹에 속함
- 자신을 생성한 부모 쓰레드의 그룹과 우선순위(기본값 5) 상속 받음
ThreadGroup getThreadGroup() // 자신이 속한 쓰레드 그룹 반환
void uncaughtException(Thread t, Throwable e) // 미처리 예외로 쓰레드 그룹의 쓰레드 종료시 메서드 자동 호출
// 쓰레드 그룹 메서드: 그룹 전체에 일괄적으로 내리는 명령
ThreadGroup(String name) // 지정된 이름의 쓰레드 그룹 생성
ThreadGroup(ThreadGroup parent, Stirng name) // 지정된 부모 쓰레드에 포함되는 쓰레드 그룹 생성
int activeCount() // 활성상태 쓰레드의 수 반환
int activeGroupcount()
void checkAccess() // 변경권한 있는지 체크
void destroy() // 모두 삭제
int enumerate(Thread[] list) // 배열 제공
int getMaxPriority() // 최대우선순위 반환
String getName() // 이름 반환
ThreadGroup getParent()
void interrupt()
void setDaemon(boolean daemon)
boolean isDaemon()
boolean isDestroyed()
void list()
boolean parentOf(ThreadGroup g)
void setMaxpriority(int pri)
9. 데몬 쓰레드(daemon thread)↔일반 쓰레드(non-daemon thread)
- 일반 쓰레드의 작업을 돕는 보조 역할
- 일반 쓰레드가 모두 종료되면 자동 종료
- 가비지 컬렉터, 자동 저장(워드), 화면자동갱신 등 사용
- 무한루프와 조건문 이용: 실행→대기→특정 조건 만족시 작업 수행→대기
- setDaemon(boolean on): 반드시 start() 호출 전 실행, 그렇지 않으면 IllegaThreadStateException 발생
boolean isDaemon() // 데몬 쓰레드인지 확인
void setDaemon(boolean on) // on → true 데몬 쓰레드로 변경
Thread t = new Thread(new Thread(new Ex13_7());
t.setDaemon(true); // 반드시 start() 호출 전 실행
t.start();
public void run() {
while(true) { // 무한루프
try {
Thread.sleep(3*1000); // 3초마다 쉬는 시간
} catch(InterruptedException e) {}
if(autoSave) autoSave(); // 자동저장
}
}
10. 쓰레드 상태
- NEW: 쓰레드 생성, start() 호출되지 않음
- RUNNABLE: 실행 또는 실행 대기(줄서기)
- BLOCKED: 일시정지
- WAITING, TIMED_WAITING: 일시정지
- TERMINATED: 쓰레드 작업 종료→소멸
11. 쓰레드 실행 제어 메서드
- static 붙은 건 자기 자신만 호출 가능: sleep(), yield()
static void sleep(long millis) // 지정된 시간(천분의 일초) 동안 쓰레드 일시정지
static void sleep(long millis, int nanos)
static void yield() // 자신의 실행시간 다른 쓰레드에게 양보
void join() // 다른 쓰레드 기다리기
void join(long millis)
void join(long millis, int nanos)
void interrupt() // sleep(), join() 깨우기
void stop() // 쓰레드 종료
void suspend() // 쓰레드 일시정지
void resume() // suspend() 재개
'Java' 카테고리의 다른 글
람다, 함수형 인터페이스, 메서드 참조 (0) | 2022.12.08 |
---|---|
쓰레드 메서드 (0) | 2022.11.19 |
애너테이션 (0) | 2022.11.08 |
열거형(enum) (0) | 2022.11.04 |
지네릭스(Generics) (0) | 2022.11.04 |