ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • join, yield, synchronized
    Java/Java 문법 종합반 강의 정리 2024. 1. 3. 17:42

    join() : 정해진 시간동안 지정한 쓰레드가 작업하는 것을 기다린다.

    - 시간을 지정하지 않았을 때는 지정한 쓰레드의 작업이 끝날 때 까지 기다린다.

     

    join 사용방법

    Thread thread = new Thread(task, "thread");
    
    thread.start();
    
    try {
        thread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    - Thread.sleep(ms), ms(밀리초) 단위로 설정된다.

    - 예외처리를 해야한다.

     - interrupt() 를 만나면 기다리는 것을 멈추기 때문에 InterruptedException 이 발생할 수 있다.

    - 시간이 지정하지 않았기 때문에 thread가 작업을 끝낼 때 까지 main 쓰레드는 기다리게 된다.

     

    쓰레드가 일을 마칠 때 까지 다른 작업을 멈춘다거나,

    해당 쓰레드가 작업을 마치는데 걸리는 시간을 측정하는 등의 사용법이 존재한다.

    자세한 코드는 별거 없어서 생략했다.

     

     

    yield() 사용방법 : 남은 시간을 다음 쓰레드에게 양보하고 쓰레드 자신은 실행대기 상태가 된다.

    public class Main {
        public static void main(String[] args) {
            Runnable task = () -> {
                try {
                    for (int i = 0; i < 10; i++) {
                        Thread.sleep(1000);
                        System.out.println(Thread.currentThread().getName());
                    }
                } catch (InterruptedException e) {
                    Thread.yield();
                }
            };
    
            Thread thread1 = new Thread(task, "thread1");
            Thread thread2 = new Thread(task, "thread2");
    
            thread1.start();
            thread2.start();
    
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            thread1.interrupt();
    
        }
    }

    - thread1 과 thread2 가 같이 1초에 한번씩 출력되다가 5초뒤에 thread1에서 intterruptException 이 발생하면서

     Thread.yield() 이 실행되어 thread1 은 실행대기 상태로 변경되면서 남은 시간은 thread2 에게 리소스가 양보된다.

     

     

    synchronized

    - 멀티 쓰레드의 경우 여러 쓰레드가 한 프로세스의 자원을 공유해서 작업하기 때문에 서로에게 영향을 줄 수 있다.

     이로 인해서 장애나 버그가 발생할 수 있다.

    - 이러한 일을 방지하기 위해 한 쓰레드가 작업중인 작업을 다른 쓰레드가 침범하지 못하도록 막는 것을

     '쓰레드 동기화(Synchronization)'라고 한다.

    - 동기화를 하려면 다른 쓰레드의 침범을 막아야하는 코드들을 '임계영역'으로 설정하면 된다.

    - 임계영역에는 Lock을 가진 단 하나의 쓰레드만 출입이 가능하다.

     - 즉, 임계영역은 한번에 한 쓰레드만 사용이 가능하다.

     

    synchronized 를 사용한 동기화

    - 실행할 메서드 또는 실행할 코드 묶음 앞에 synchronized 를 붙여서 임계영역을 지정하여 다른 쓰레드의 침범을

     막을 수 있다. (침범을 막다. = Lock을 걸다.)

     

    임계영역 지정 방법 두가지

    1. 메서드 전체를 임계영역으로 지정한다.

    public synchronized void asyncSum() {
    	  ...침범을 막아야하는 코드...
    }

     

    2. 특정 영역을 임계영역으로 지정한다.

    synchronized(해당 객체의 참조변수) {
    		...침범을 막아야하는 코드...
    }

     

    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 를 걸지 않았다면, if문의 조건인 storedApple > 0 이 아님에도 불구하고 while문의 로직을 실행한다.

    하지만 synchronized 를 건 덕에, eatApple 메서드 안에서 임계영역(if문)을 수행할 수 있는 것은 하나의 쓰레드로 제한된다.

    사과가 0개가 된 이후엔 조건문을 통과하지 못한 나머지 쓰레드들 또한 0개의 사과를 출력한다.

     

    git 사용에서도 그랬듯이, 충돌 상황이라는 것은 많이 겪어보면서 배우는 것이 가장 빠르다.

    때가 되면 이 내용을 떠올리며 최대한 많이 부딪쳐보자.

    'Java > Java 문법 종합반 강의 정리' 카테고리의 다른 글

    Lock, Conditon  (6) 2024.01.03
    wait(), notify()  (1) 2024.01.03
    쓰레드의 상태와 제어  (2) 2024.01.03
    데몬 쓰레드, 쓰레드 우선순위, 쓰레드 그룹  (0) 2024.01.03
    쓰레드 사용법  (1) 2024.01.03
Designed by Tistory.