자바 스레드
IT 위키
- 자바에서 스레드를 생성하고 제어하는 방법
자바는 언어 차원에서 멀티스레드를 지원한다. main 메서드도 메인 스레드라는 하나의 스레드에서 실행된다.
class MyThread extends Thread {
public void run() { System.out.println("Hello"); }
}
MyThread t = new MyThread();
t.start();
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()을 실행한다.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를 쓰면 직접 동기화하는 것보다 안전하고 간결하다.
