//main 스레드
Thread mainThread = Thread.currentThread();
log("mainThread = " + mainThread);
log("mainThread.threadId()" + mainThread.threadId()); //자바에서 고유값 정함
log("mainThread.getName()" + mainThread.getName()); //사용자가 정할 수있음
log("mainThread.getPriority()" + mainThread.getPriority()); //우선 순위 기본이 5 우선순위가 높을수록 많이 사용된다함
log("mainThread.getThreadGroup()" + mainThread.getThreadGroup());
log("mainThread.getState()" + mainThread.getState()); //스레드가 실행될 수 있는 상태 RUNNABLE
// myThread 스레드
Thread myThread = new Thread(new HelloRunnable(), "myThread");
log("myThread= " + myThread);
log("myThread.threadId()= " + myThread.threadId());
log("myThread.getName()= " + myThread.getName());
log("myThread.getPriority()= " + myThread.getPriority());
log("myThread.getThreadGroup()= " + myThread.getThreadGroup());
log("myThread.getState()= " + myThread.getState()); // NEW는 실행되지 않은 상태
스레드를 생성할 땐 실행할 인터페이스 구현체와 스레드 이름을 전달할 수 있다.
Thread myThread = new Thread(new HelloRunnable(), "myThread");
Thread 생성주기
NEW
생성되고 실행되지 않은 상태 (start()가 안된 상)
RUNNABLE
start() 호출 되면 현 상태가 되며, 멀티태스킹 중일 때 실제실행 중인 상태와 스케줄러에 들어가 대기 상태 모두 현 상태로 취급
위 상태 외 다른 상태는 CPU 사용하지 않음
BLOCKED(차단 상태)
동기화 락을 얻기 위해 대기 상태
synchronized와 관련
WAITING(대기상태)
wait(), join() 호출시 현 상태가 됨
TIMED WAITING(시간 제한 대기 상태)
sleep(long millis), wait(long millis), join(long millis) 호출시 현 상태가 됨
TERMINATED(종료상태)
스레드 실행이 완료된 상태
정상 종료나 예외 발생 종료시 현 상태가 됨
스레드 종료시 다시 시작 안됨 (다시 만들어야 함)
public static void main(String[] args) {
log("start");
Thread thread1 = new Thread(new Job(), "thread-1");
Thread thread2 = new Thread(new Job(), "thread-2");
thread1.start();
thread2.start();
log("end");
}
static class Job implements Runnable {
@Override
public void run() {
log("작업시작");
sleep(2000);
log("작업완료");
}
}
위 코드의 결과는 아래 캡처와 같다.
main 스레드가 thread-1, thread-2에게 작업을 지시하고 main 스레드는 end로 끝내버린다.
이렇게 된다면 thread-1, thread-2의 작업에 대한 결과 값을 main 스레드가 받아서 하고 싶을때 문제가 생긴다.
그럴때 join을 사용한다.
public static void main(String[] args) throws InterruptedException {
log("start");
SumTask task1 = new SumTask(1, 50);
SumTask task2 = new SumTask(51, 100);
Thread thread1 = new Thread(task1, "thread-1");
Thread thread2 = new Thread(task2, "thread-2");
thread1.start();
thread2.start();
//스레드가 종료될때까지 대기
log("join() - main 스레드가 thread1, thread2 종료까지 대기");
thread1.join();
thread2.join();
log("join() - 대기완료");
log("task1.result = " + task1.result);
log("task2.result = " + task2.result);
int sumAll = task1.result + task2.result;
log("sumAll = " + sumAll);
log("end");
}
static class SumTask implements Runnable{
int startValue;
int endValue;
int result;
public SumTask(int startValue, int endValue) {
this.startValue = startValue;
this.endValue = endValue;
}
@Override
public void run() {
log("작업 시작");
sleep(2000);
int sum = 0;
for (int i = startValue; i <= endValue; i++) {
sum += i;
}
result = sum;
log("작업 완료 result = " + result);
}
}
thread1.join(); -> TERMINATED
thread2.join(); -> TERMINATED
가 되면 다음 코드가 실행된다.
만약 thread-1, thread-2의 작업이 너무 길어지는 경우는 어떻게 해야할까..
최대 대기 시간을 정해야 하는 경우가 생길 수 있다.
그럴땐
.join(long millis); 시간을 정해주면 된다.
.join()과 같이 시간을 안넣어주면 WATING 상태인데
.join(long millis)와 같이 시간을 넣어주면 TIMED_WAITING 상태가 된다.
'공부 > Java' 카테고리의 다른 글
제네릭 사용이유 (0) | 2024.10.02 |
---|---|
메모리 가시성 (0) | 2024.09.20 |
스레드 생성과 실행 (0) | 2024.09.16 |
프로세스와 스레드란 (0) | 2024.09.16 |
래퍼, Class 클래스란 (0) | 2024.05.30 |