쓰레드 메서드인 join, yield, synchrozied를 배우고 기록한다.
join은 지정된 쓰레드가 특정 쓰레드가 끝나는걸 기다리도록 만들어주는 메서드이다.
예를 들어 main 쓰레드와 thread1을 함께 실행할 때 메인 쓰레드는 thread1이 끝나는걸 기다리지 않는다.
하지만 thread1.join()을 선언하여 main 메서드가 thread1이 종료될 때까지 일시정지 상태에 놓여지게 된다
try{
thread1.join();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("소요시간 = " + (System.currentTimeMillis() - start));
// join() 메서드를 사용하지 않았을 때
// 소요시간 = 0
// join() 메서드를 사용했을 때
// 소요시간 5005
해당 쓰레드를 실행대기 상태로 강제 전환 시키는 메서드이다.
try{
for(int i = 0; i < 10; i++){
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
}
}catch(InterruptedException e){
Thread.yield(); // 실행 대기 상태로 전환
}
실행중인 작업에 Lock을 걸어 임계영역으로 지정해준다.
(*임계영역 = Lock을 가진 단 하나의 쓰레드만 출입 가능하다.)
이를 통해 동기화를 가능하게 한다.
// synchronized 예시 코드
package thread.sync;
public class Main {
public static void main(String[] args) {
AppleStore appleStore = new AppleStore();
Runnable task = () -> {
while(appleStore.getStoredApple() > 0){
appleStore.eatApple();
System.out.println("남은 사과의 수 = " + appleStore.getStoredApple());
}
};
for(int i = 0; i < 3; i++){
new Thread(task).start();
}
}
}
class AppleStore{
private int storedApple = 10;
public int getStoredApple(){
return storedApple;
}
public void eatApple() {
synchronized (this){
if(storedApple > 0){
try {
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
storedApple -= 1;
}
}
}
}
위 코드를 기준으로 synchronized를 사용하지 않았을 때 남은 사과의 수가 음수로 넘어가게 된다.
그 이유는 사과의 수가 1개가 남았을 때 3개의 쓰레드가 동시에 작업을 실행하기 때문이다.
따라서 synchronized를 사용하지 않았을 때 0, -1, -2가 되어버린다.
사용했을 때 0,0,0으로 출력된다.