자바의정석 13장 쓰레드

ch13-1 프로세스와 쓰레드(process & thread)

  • 프로세스: 실행죽인 프로그램, 자원(resource)과 쓰레드로 구성
  • 쓰레드: 프로세스 내에서 실제 작업을 수행
    모든 프로세스는 최소한 하나의 쓰레드를 가지고 있다.

(프로세스 : 쓰레드 = 공장 : 일꾼)

  • 싱글 쓰레드 프로세스
    = 자원 + 쓰레드

  • 멀티 쓰레드 프로세스
    = 자원 + 쓰레드 + 쓰레드 +...+ 쓰레드

"하나의 새로운 프로세스를 생성하는 것보다
하나의 새로운 쓰레드를 생성하는 것이 더 적은 비용이 든다."

  • 2 프로세스 1 쓰레드 vs 1 프로세스 2 쓰레드

ch13-2 멀티쓰레드의 장단점

"대부분의 프로그램의 멀티쓰레드로 작성되어 있다.
그러나, 멀티쓰레드 프로그래밍이 장점만 있는 것은 아니다."

장점

  • 시스템 자원을 보다 효율적으로 사용
  • 사용자에 대한 응답성이 향상
  • 작업이 분리되어 코드가 간결
    "여러 모로 좋다"

단점

  • 동기화에 주의
  • 교착상태가 발생하지 않도록 주의
  • 각 쓰레드가 효율적으로 고르게 실행될 수 있도록 해야 함
    "프로그래밍할 때 고려해야 할 사항들이 많다."

ch13-3 쓰레드의 구현과 실행

  1. Thread클래스를 상속(자바는 단일상속)
MyThread t1 = new MyThread(); //쓰레드 생성
t1.start() //쓰레드 실행
  1. Runnable 인터페이스를 구현(더 유연하다)
Runnable r = new MyThread2();
Thread t2 = new Thread(r); //Thread(Runnable r)
//Thread t2 = new Thread(new MyThread2());
t2.start();

ch13-5 쓰레드의 실행 - start()

  • 쓰레드를 생성한 후에 start()를 호출해야 쓰레드가 작업을 시작한다.
  • OS스케쥴러에 따라 실행 순서가 결정(OS에 JVM이 종속적)

ch13-6 start()와 run()

ch13-7 main쓰레드

  • main메서드의 코드를 수행하는 쓰레드
  • 쓰레드는 '사용자 쓰레드'와 '데몬 쓰레드' 두 종류가 있다.
    "실행 중인 사용자 쓰레드가 하나도 없을 때 프로그램은 종료된다."

ch13-8 싱글쓰레드와 멀티쓰레드

  • 싱글쓰레드 : 순차적으로 실행
  • 멀티쓰레드 : OS스케쥴러의 로직에 따라 실행 순서 결정

ch13-11 쓰레드의 I/O블락킹(blocking)

ch13-14 쓰레드의 우선순위(priority of thread)

  • 작업의 중요도에 따라 쓰레드의 우선순위를 다르게 하여 특정 쓰레드가 더 많은 작업시간을 갖게 할 수 있다.
void setPriority(int newPrioirity); //쓰레드의 우선순위를 지정한 값으로 변경
int getPrioirity(); //쓰레드의 우선순위를 반환

public static final int MAX_PRIORITY = 10 //최대우선순위
public static final int MIN_PRIORITY = 1 //최소우선순위
public static final int NORM_PRIORITY = 5 //보통우선순위

ch13-16 쓰레드그룹

  • 서로 관련된 쓰레드를 그룹으로 묶어서 다루기 위한 것
  • 모든 쓰레드는 반드시 하나의 쓰레드 극룹에 포함되어 있어야 한다.
  • 쓰레드 그룹을 지정하지 않고 생성한 쓰레드는 'main쓰레드 그룹'에 속한다.
  • 자신을 생성한 쓰레드(부모 쓰레드)의 그룹과 우선순위를 상속받는다.

ch13-17 쓰레드 그룹의 메서드

ch13-18 데몬 쓰레드(daemon thread)

  • 일반 쓰레드(non-daemon thread)의 작업을 돕는 보조적인 역할을 수행
  • 일반 쓰레드가 모두 종료되면 자동적으로 종료된다.
  • 가비지 컬렉터, 자동저장, 화면 자동갱신 등에 사용된다.
  • 무한루프와 조건문을 이용해서 실행 후 대기하다가 특정조건이 만족되면 작업을 수행하고 다시 대기하도록 작성

ch13-20 쓰레드의 상태

NEW : 쓰레드가 생성되가 아직 start()가 호출되지 않은 상태
RUNNABLE : 실행 중 또는 실행 가능한 상태
BLOCKED : 동기화블럭에 의해서 일시정지된 상태
WAITING, : 쓰레드의 작업이 종료되지는 않았지만 실행가능하지 않은 일시정지상태
TILMED_WAITING : 일시정지시간이 지정된 경우
TERMINATED : 쓰레드의 작업이 종료된 상태

ch13-21 쓰레드의 실행제어

  • 쓰레드의 실행을 제어할 수 있는 메서드가 제공됨
    이 들을 활용해서 보다 효율적인 프로그램을 작성 할 수 있다.
static sleep(long millis)
static sleep(long millis, int nanos)

join()
join(long millis)
join(long millis, int nanos)

interrupt()

stop()

suspend()

resume()

static yield()

//static은 쓰레드 자기 자신에게만 호출가능

ch13-22 sleep()

  • 현재 쓰레드를 지정된 시간동안 멈추게 한다.
static void sleep(long millis) //천분의 일초 단위
static void sleep(long millis, int nanos) //천분의 일초 + 나노초
  • 예외처리를 해야한다.(InterrupedException이 발생하면 깨어남)
void delay(long millis) {
try {
	Thread.sleep(1, 500000); //쓰레드를 0.0015초 동안 멈추게 한다.
} catch(InterruptedException e) {}
}
  • 특정 쓰레드를 지정해서 멈추게 하는 것은 불가능하다.

ch13-24 interrupt()

  • 대기상태(WAITING)인 쓰레드를 실행대기 상태(RUNNABLE)로 만든다.
void interrupt() 
//쓰레드의 interrupted상태를 false에서 true로 변경.
boolean isInterrupted()
//쓰레드의 interrupted상태를 반환.
satic boolean interrupted() 
//현재 쓰레드의 interrupted상태를 알려주고, false로 초기화

ch13-26 suspend(), resume(), stop()

  • 쓰레드의 실행을 일시정지, 재개, 완전정지 시킨다.
void suspend() 
//쓰레드를 일시정지 시킨다.
void resume()
//suspend()에 의해 일시정지된 쓰레드를 실행대기상태로 만든다.
void stop()
//쓰레드를 즉시 종료시킨다.
  • suspend(), resume(), stop()은 deprecated됨.
    --> dead-lock(교착상태)에 빠지기 쉬워 진행이 안되게 할 수 있다.

ch13-28 join()

  • 지정된 시간동안 특정 쓰레드가 작업하는 것을 기다린다.
void join() 
//작업이 모두 끝날 때까지
void join(long millis)
//천분의 일초 동안
void join(long millis, int nanos)
//천분의 일초 + 나노초 동안

ch13-29 yield()

  • 남은 시간을 다음 쓰레드에게 양보하고, 자신(현재 쓰레드)은 실행대기한다.
  • yield()와 interrupt()를 적절히 사용하면, 응답성과 효율을 높일 수 있다.

ch13-30 쓰레드의 동기화(synchonization)

  • 멀티 쓰레드 프로세스에서는 다른 쓰레드의 작업에 영향을 미칠 수 있다.
  • 진행중인 작업이 다른 쓰레드에 간섭하지 않게 하려면 '동기화'가 필요
    (쓰레드의 동기화 : 한 쓰레드가 진행중인 작업을 다른 쓰레드가 간섭하지 못하게 막는 것)
  • 동기화하려면 간섭받지 않아야 하는 문장들을 '임계 영역'으로 설정
  • 임계영역은 락(lock)을 얻은 단 하나의 쓰레드만 출입가능(객체 1개에 락 1개)

ch13-31 synchonized를 이용한 동기화

  • synchronized로 임계영역(lock이 걸리는 영역)을 설정하는 방법 2가지
  1. 메서드 전체를 임계 영역으로 지정
  2. 특정한 영역을 임계영역으로 지정

ch13-34 wait()과 notify()

  • 동기화의 효율을 높이기 위해 wati(), notify()를 사용.
  • Object클래스에 정의되어 있으며, 동기화 블록 내에서만 사용할 수 있다.
wait() - 객체의 lick을 풀고 쓰레드를 해당 객체의 waiting pool에 넣는다.
notify() - waiting pool에서 대기중인 쓰레드 중의 하나를 깨운다
notifyAll() - waiting pool에서 대기중인 모든 쓰레드를 깨운다

좋은 웹페이지 즐겨찾기