[자바의정석]Java - Thread(쓰레드) #014

프로세스와 쓰레드

프로세스(공장)

  • 실행 중인 프로그램, 자원(resuorces)과 쓰레드로 구성

쓰레드(일꾼)

  • 프로세스 내에서 실제 작업을 수행,
    모든 프로세스는 최소한 하나의 쓰레드를 가지고 있다

프로세스,쓰레드

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

프로세스,쓰레드 장단점

  • 장점 :
  1. 시스템 자원을 보다 효율적으로 사용할 수 있다
  2. 사용자에 대한 응답성이 향상된다
  3. 작업이 분리되어 코드가 간결해 진다
  • 단점 :
  1. 동기화(synchronization)에 주의해야 한다
  2. 교착상태(dead-lock)가 발생하지 않도록 주의해야 한다
  3. 각 쓰레드가 효율적으로 고르게 실행될수 있게 해야 한다

쓰레드의 구현과 실행

구현과 실행

  • Thread클래스를 상속
    run()을 오버라이딩
  • Runnable 인터페이스를 구현
    추상메서드 run()을 구현

쓰레드의 실행 start()

  • 쓰레드를 생성한 후에 start를 호출해야 쓰레드가 작업을 시작한다
  • os스케줄러가 실행 순서를 결정
  • start()시 즉시 실행되는게 아님 먼저 start라고 써준다고 먼저 실행되는 것도 아니다 os 스케줄러가 결정.

start() 와 run()

  • 우리가 작성한건 run()인데 왜 start()를 호출할까?
  • 호출스택에 각각 메서드가 있음 start()를 호출해서
    새로운 스택에 run()을 올려 실행되게 할수있다

싱글,멀티쓰레드 와 쓰레드의I/O 블록킹

main쓰레드

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

쓰레드의 I/O블락킹'

  • 싱글 쓰레드의 경우 사용자로부터 입력을 기다리는 구간 아무일도 하지 않는다
  • 멀티 쓰레드의 경우 사용자로부터 입력을 기다리는 구간 다른 쓰레드의 작업이 수행될 수 있다

쓰레드의 우선순위,쓰레드 그룹

쓰레드의 우선순위

  • 작업의 중요도에 따라 쓰레드의 우선순의를 다르게 하여 특정 쓰레드가 더 많은 작업 시간을 갖게 할 수 있다
  • void setPriority(int x) 쓰레드 우선순위를 지정한 값으로 변경
    1~10 범위(희망사항)
  • int getPriority 쓰레드 우선순위를 반환한다
  • 우선순위가 높을 수록 무조건 더 빨리 끝나는건아님 빨리 끝날 확률은 더 높아진다

쓰레드그룹

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

데몬쓰레드, 쓰레드의 상태

데몬쓰레드

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

쓰레드의 상태

  • NEW 쓰레드가 생성되고 아직 start() 전의 상태
  • RUNNABLE 실행중 또는 실행 가능 상태
  • BLOCK 동기화 블럭에 의해서 일시정지된 상태
  • WAITING,TIMED_WAITING 쓰레드의 작업이 종료되지는 않았지만 실행가능하지 않은 일시정지 상태
  • TERMINATED 쓰레드의 작업이 종료된 상태

쓰레드의 실행제어 메소드

  • sleep(), 쓰레드 일시정지
  • join(시간), 지정시간동안 다른 쓰레드가 실행되도록 한다
  • interrupt(), sleep()나 join() 에의해 일시정지인 상태를 깨워서 실행대기로 만듬
  • stop(), 쓰레드 종료
  • suspend(), 쓰레드를 일시정지
  • resume(), suspend()에의해 정지되어있는걸 실행대기로 만듬
  • yeild(), 양보

sleep()

  • 현재 쓰레드를 지정된 시간동안 멈추게한다
  • 자기 자신만 정지할수있다
  • 예외처리를 해야 한다(InterruptedException이 발생하면 깨어남)
  • 특정 쓰레드를 지정해서 멈추게 하는 것은 불가능

interrupt()

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

suspend(),resume(),stop()

  • suspend(), 쓰레드를 일시정지 시킨다

  • resume(), suspend() 에 의해 일시정지된 쓰레드를 실행 대기 상태로 만든다

  • stop(), 쓰레드 종료

  • 교착상태 때문에 deprecated 됨 그래서 직접 생성해서 사용하면됨

join()

  • void join(시간)
  • 지정된 시간동안 특정 쓰레드가 작업하는 것을 기다린다
  • 예외처리를 해서 사용해야한다
  • 예시 : GC(가비지 컬렉터)
    10초마다 가비지 컬렉터 수행한다 사용하지 않는 객체 제거
    사용할 수 있는 메모리를 확인해서
    메모리 부족한 경우 gc.interrupt로 잠자는 쓰레드를 깨운다
    깨운다음 join()으로 gc가 작업할 시간을준다
    그 후에 메모리를사용 (이렇게 기다릴 때 사용한다)

yield()

  • 남은 시간을 다음 쓰레드에게 양보하고, 자신(현재 쓰레드)은 실행대기한다
  • yield()와 interrupt()를 적절히 사용하면 응답성과 효율을 높여준다
  • yield()가 완벽히 동작한다는 보장은 없다 그냥 os스케줄러에 통보

쓰레드의 동기화

쓰레드의 동기화(synchronization)

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

synchronized를 이용한 동기화

  • synchronized로 임계영역(lock이 걸리는 영역)을 설정한느 방법 2가지
  • 1.메서드 전체를 임계영역으로 지정
public synchronized void 메서드(){
}
  • 2.특정한 영역을 임계영역으로 지정
synchronized(참조변수){
}

wait(),notify()

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

wait(),notify() 예제1

  • 요리사는 Table에 음식추가 , 손님은 Table의 음식을 소비
  • 요리사와 손님이 같은 객체를 공유하기 '때문에 동기화가 필요하다'
  • 공유하는 객체가 있다면 동기화하자
  • 예상되는 문제점 :
    음식이 없을때 , 손님이 Table의 lock을 쥐고 안놓는다
    음식이 없을때 , wait으로 손님이 lock을 풀고 요리사가 음식을 추가 할 수있게한다
    요리가사 음식을 추가하면, notify()르 손님에게 알리자(손님 lock획득)

좋은 웹페이지 즐겨찾기