멀티태스킹 : 하나의 응용프로그램이 여러 개의 작업(태스크)을 동시에 처리
스레드와 멀티스레딩
스레드 : 사용자가 작성한 코드로서, JVM에 의해 스케줄링되어 실행되는 단위
자바는 하나의 응용프로그램이 여러 개의 스레드로 구성 가능 => 시간 지연을 줄임
자바스레드 : JVM에 의해 스케쥴되는 실행 단위의 코드 블럭, 생명 주기는 JVM에 의해 관리됨
[JVM과 멀티스레드의 관계]
하나의 JVM은 하나의 자바 응용 프로그램만 실행
하나의 응용프로그램은 하나 이상의 스레드로 구성 가능
스레드 만들 때 주의 사항
1) run() 메소드가 종료하면 스레드는 종료
2) 한번 종료한 스레드는 다시 시작시킬 수 없다. 다시 스레드 객체를 생성하고 start()를 호출해야 함
3) 한 스레드에서 다른 스레드를 강제 종료할 수 있다.
스레드 상태
1) NEW : 생성된 직후/ 스레드가 생성되었지만 스레드가 아직 실행할 준비가 되지 않았음
2) RUNNABLE : 스레드가 현재 실행되고 있거나 실행 준비되어 스케쥴링을 기다리는 상태
3) WAITING : wait()를 호출한 상태 / 스레드 동기화를 위해 사용
4) TIMED_WAITING : sleep(n)을 호출하여 n 밀리초 동안 잠을 자고 있는 상태
5) BLOCK : 스레드가 I/O 작업을 요청하면 JVM이 자동으로 BLOCK 상태로 만ㄷ름
6) TERMINATED : 스레드가 종료한 상태
=>스레드 상태는 JVM에 의해 기록 관리됨
스레드 우선 순위와 스케쥴링
1) 스레드 우선 순위는 응용프로그램에서 변경 가능
2) 스레드는 부모 스레드와 동일한 우선순위 값을 가지고 탄생
3) 동일한 우선순위의 스레드는 돌아가면서 스케쥴링(라운드 로빈)
main()을 실행하는 main 스레드
JVM은 응용프로그램을 실행 시작할 때 스레드 생성 - main 스레드
JVM은 main 스레드에게 main() 메소드 실행하도록함 => main() 메소드가 종료하면 main 스레드 종료
스레드 종료 방법 - 종료된 스레드를 다시 살릴 수는 없음
1) 스스로 종료 : run() 메소드 리턴 (return 하지 않으면 스레드는 종료하지 않음)
2) 타 스레드에서 강제 종료 : interrupt() 메소드 사용 -> 스레드의 catch문 실행해서 종료
3) flag를 이용한 종료 : 스레드 A가 스레드 B의 flag를 true로 만들면, 스레드 B가 스스로 종료하는 방식
스레드 동기화
멀티스레드 프로그램 작성시 주의점 : 다수의 스레드가 공유 데이터에 동시에 접근하는 경우 -> 예상치 못한 결과 발생 가능
스레드 동기화 : 공유 데이터에 동시에 접근하는 다수의 스레드가 공유 데이터를 배타적으로 접근하기 위해 상호 협력 하는 것
동기화의 핵심 - 스레드의 공유 데이터에 대한 배타적 독점 접근 보장
<방법>
1) synchronized로 동기화 블록 저장 -> 한 아이만 모니터를 장악
synchronized 블록 지정 - synchronized 키워드 : 한 스레드가 독점 실행해야 하는 부분(동기화 코드)을 표시하는 키워드
: 임계 영역(독점적으로 공유 데이터를 다루는 프로그램 코드) 표기 키워드
- 진입할 때 락(lock)이 걸리고 빠져나올 때 락이 풀리는(unlock) 동작이 자동으로 이루어지도록 컴파일 된다.
2) wait()-notify() 메소드로 스레드 실행 순서 제어
동기화 객체 : 두 개 이상의 스레드 동기화에 사용되는 객체
[동기화 메소드]
- wait() : 다른 스레드가 notify()를 불러줄 때까지 기다린다.
- notify() : wait()중인 스레드를 깨우고 RUNNABLE 상태로 만듦,
2개 이상의 스레드가 대기중이라도 오직 한 스레드만 깨운다.
- notifyAll() : wait()를 호출하여 대기중인 모든 스레드를 깨우고 모두 RUNNABLE 상태로 만듦
=> synchronized 블록 내에서만 사용되어야 함
wait(), notify(), notifyAll()은 Object의 메소드
-> 모든 객체가 동기화 객체가 될 수 있음, Thread 객체도 동기화 객체로 사용 가능