자바 스레드

IT 위키
자바에서 스레드를 생성하고 제어하는 방법

자바는 언어 차원에서 멀티스레드를 지원한다. main 메서드도 메인 스레드라는 하나의 스레드에서 실행된다.

스레드를 만드는 두 가지 방법

[편집 | 원본 편집]

Thread 클래스를 상속

[편집 | 원본 편집]
class MyThread extends Thread {
    public void run() { System.out.println("Hello"); }
}

MyThread t = new MyThread();
t.start();

Runnable 인터페이스를 구현

[편집 | 원본 편집]
class Car implements Runnable {
    public void run() { System.out.println("Hello"); }
}

Thread t1 = new Thread(new Car());   // Runnable 구현 객체를 Thread 에 넘긴다
t1.start();

실무에서는 Runnable 쪽을 권장한다. 자바는 다중 상속을 지원하지 않아 Thread 를 상속하면 다른 클래스를 상속할 수 없기 때문이다. 또 작업(Runnable)과 실행 주체(Thread)를 분리하는 설계가 더 유연하다.

start() 와 run()

[편집 | 원본 편집]
  • start() : 새 스레드를 만들어 그 위에서 run() 을 실행한다.
  • run() : 그냥 메서드 호출이다. 새 스레드가 만들어지지 않고 현재 스레드에서 순차 실행된다.
  • 한 번 start() 한 스레드를 다시 start() 하면 IllegalThreadStateException 이 발생한다.

생명 주기

[편집 | 원본 편집]
NEW  --start()-->  RUNNABLE  <-->  RUNNING
                      |  ^
      sleep/wait/join |  | 시간 만료, notify(), 대상 종료
                      v  |
                   BLOCKED / WAITING / TIMED_WAITING
                      |
                run() 종료
                      v
                 TERMINATED

주요 메서드

[편집 | 원본 편집]
메서드 설명
start() 스레드를 시작한다
run() 스레드가 수행할 작업 본문. 직접 호출하지 않는다
sleep(ms) 지정 시간 동안 멈춘다. 정적 메서드다
join() 해당 스레드가 끝날 때까지 기다린다
interrupt() 대기 중인 스레드에 인터럽트를 건다
setPriority(n) 우선순위를 1~10 으로 설정한다(기본 5). 보장이 아니라 힌트
setDaemon(true) 데몬 스레드로 지정한다. 일반 스레드가 모두 끝나면 함께 종료된다

stop(), suspend(), resume() 은 교착 상태를 유발할 수 있어 더 이상 쓰지 않는다(deprecated).

동기화

[편집 | 원본 편집]

여러 스레드가 같은 자원에 동시에 접근하면 값이 깨질 수 있다. 자바는 synchronized 키워드로 임계 구역을 보호한다.

public synchronized void add(int v) { total += v; }   // 메서드 전체

synchronized (lock) { ... }                            // 블록 단위
  • wait() / notify() / notifyAll() 로 스레드 간 협력을 제어한다. 이 메서드들은 synchronized 블록 안에서만 호출할 수 있다.
  • java.util.concurrent 패키지의 ExecutorService, ConcurrentHashMap, AtomicInteger 를 쓰면 직접 동기화하는 것보다 안전하고 간결하다.

같이 보기

[편집 | 원본 편집]