Thread 상태
Thread로 객체를 생성하면 우선 실행대기 상태로 들어간다(작업을 할당받지 못한 상태). 실행대기 상태에 있는 Thread 중 선택된 Thread가 run()을 실행한다(실행상태). 이때 run() 메소드가 끝나지 않아도 다시 실행대기 상태로 돌아가며 번갈아 가며 사용할 수 있다. 경우에 따라 run 중인 Thread를 일시정지 시킬수도 있다(sleep()메소드). 일시정지 이후에는 다시 실행 대기 상태로 간다.
실행중인 Thread 상태를 변경하는 것을 말한다. 상태를 제어하는 메소드는 아래 그림과 같다.
실행중인 Thread를 일정 시간 멈출 때 사용한다.
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Thread는 다른 Thread와 독립적으로 실행되는 것이 기본이지만, 다른 Thread가 종료될 때까지 기다렸다가 실행해야 하는 경우가 있다.
이런 경우에 join() 메소드를 사용한다.
public static void main(String args[]){
SumThread sumThread = new SumThread();
sumThread.start();
try {
sumThread.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("합 : " + sumThread.getSum());
}
public class SumThread extends Thread {
private long sum;
public long getSum() {
return sum;
}
public void setSum(long sum) {
this.sum = sum;
}
public void run() {
for(int i = 0; i <= 100; i++) {
sum += 1;
}
}
}
Main.java
public class Main {
public static void main(String[] args) {
WorkObject sharedObject = new WorkObject(); // 고유 객체 생성
ThreadA threadA = new ThreadA(sharedObject);
ThreadB threadB = new ThreadB(sharedObject);
threadA.start();
threadB.start();
}
}
WorkObject
public class WorkObject {
public synchronized void methodA() {
System.out.println("Thread의 methodA() 작업 실행");
notify(); // 일시 정지에 있는 ThreadB를 실행 대기 상태로 만듦
try {
wait(); // ThreadA를 일시 정지 상태로 만듬
} catch (InterruptedException e) {
}
}
public synchronized void methodB() {
System.out.println("Thread의 methodB() 작업 실행");
notify(); // 일시 정지에 있는 ThreadA를 실행 대기 상태로 만듦
try {
wait(); // ThreadB를 일시 정지 상태로 만듬
} catch (InterruptedException e) {
}
}
}
ThreadA
public class ThreadA extends Thread {
private WorkObject workObject;
public ThreadA(WorkObject workObject) {
this.workObject = workObject;
}
@Override
public void run() {
for(int i = 0; i < 10; i++) {
workObject.methodA();
}
}
}
ThreadB
public class ThreadB extends Thread {
private WorkObject workObject;
public ThreadB(WorkObject workObject) {
this.workObject = workObject;
}
@Override
public void run() {
for(int i = 0; i < 10; i++) {
workObject.methodB();
}
}
}
stop 플래그를 이용하는 방법
Main
public class Main {
public static void main(String[]args) throws InterruptedException {
RunTread runTread = new RunTread();
runTread.start();
Thread.sleep(1000);
runTread.setStop(true);
}
}
**RunThread
public class RunTread extends Thread {
private boolean stop; // stop 플래그 설정
public void setStop(boolean stop) {
this.stop = stop;
}
public void run() {
while(!stop) {
System.out.println("Thread 실행 중...");
}
System.out.println("자원 정리");
System.out.println("실행 종료");
}
}
interrupt() 메소드 이용방법
interrupt 메소드는 스레드가 일시정지 상태에 있을 때 InterruptException 예외를 발생시키다.
이것을 이용해 run() 메소드를 정상 종료 시킬 수 있다.
Main
public class Main {
public static void main(String[]args) {
InterruptThread interThread = new InterruptThread();
interThread.start();
try {
Thread.sleep(1000);
} catch(InterruptedException e) { }
interThread.interrupt();
}
}
InterruptThread
public class InterruptThread extends Thread {
public void run() {
try {
while(true) {
System.out.println("쓰레드 실행 중...");
Thread.sleep(1);
}
} catch(InterruptedException e) {
}
System.out.println("자원 정리");
System.out.println("실행 종료");
}
}