본문 바로가기
Java

Java_5주차-(2)

by shulk 2023. 10. 17.

1.join()

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

* 괄호안 시간을 지정하지 않으면 지정한 쓰레드의 작업이 끝날 때까지 기다린다.

* join은 static형이 아니라 특정 쓰레드를 지정 할 수 있다.

* 밑에 코드를 보면 Main쓰레드는 thread의 작업 종료전까지 기다려서 5초 지난 순간 "체크"출력하고 "소요시간 5.0003" 출력한다.

public class Main {
    public static void main(String[] args) {
        Runnable task = () -> {
            try {
                Thread.sleep(5000); // 5초
                System.out.println("체크");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        Thread thread = new Thread(task, "thread");

        thread.start();

        long start = System.currentTimeMillis();

        try {
            thread.join();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // thread 의 소요시간인 5000ms 동안 main 쓰레드가 기다렸기 때문에 5000이상이 출력됩니다.
        System.out.println("소요시간 = " + (System.currentTimeMillis() - start));
    }
}

 

2. yield()

* 남은 시간을 다음 쓰레드에게 양보하고 쓰레드 자신은 실행대기 상태가 된다

* 코드를 보면 thread1, thread2 둘다 1초에 한번씩 자기 쓰레드 이름 출력하다가 thread1.interrupt();에 의해서 thread1이

InterruptedException 발생하면서 Thread.yield(); 실행되어 thread1은 대기 상태로 변경되고 thread2만 계속 실행해서 thread2 자기 쓰레드 이름 출력하다가 끝난다. 

( yield()는 운영체제의 cpu스케줄링에서 선점형 스케줄링이랑 관련있는듯한? )

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();

    }
}

3.  synchronized

쓰레드의 동기화이고 Synchronization로 임계영역을 지정하는거다.

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

(운영체제에서 했던  동기화 기법중 뮤텍스 락,세마포를 말하는듯한)

4. wait() , notify() , Lock, Condition

(3번의 Synchronization도 그렇고 4번의 기능들 모두 지금 단계에서는 실제로 사용 하기도 어려워서 일단 이런게 있고,어떠한 기능인지만 알아두기)

 

* wait()실행중이던 쓰레드는 락을 반납하고 대기상태로

 

* notify()wait로 인해 대기큐에 있는 쓰레드를 notify로 그 쓰레드를 불러서 다시 락을 얻어 진행할 수 있게한다.

 

* Lock:  synchronized 블럭으로 동기화하면 자동적으로 Lock이 걸리고 풀리지만, 같은 메서드 내에서만 Lock을 걸 수 있다는 제약이 있어서 이 제약을 해결하기 위해 Lock클래스 이용한다.

종류는-> ( ReentrantLock , ReentrantReadWriteLock , StampedLock 등 있다)

 

* Condition: wait() & notify()의 문제점인 waiting pool 내 쓰레드를 구분하지 못한다는 것을 해결한 것이 Condition 이다.

그래서 wait() & notify() 대신 await() & signal() 을 사용한다

 

5. 함수를 값으로 전달

예를들어 메소드의 매개변수를 함수로 하는경우 -> 함수형 인터페이스 사용한다.

 

*함수형 인터페이스 특징 ↓

* 함수형 인터페이스 코드 ex) ↓ 

 

6. 람다식

* 형태는 () -> {} 인데 {}안에 코드 한줄뿐이면 {}생략 가능

'Java' 카테고리의 다른 글

Java_5주차-(1)  (0) 2023.10.16
Java_4주차  (0) 2023.10.16
Java_3주차-(2)  (0) 2023.10.13
Java_3주차-(1)  (0) 2023.10.13
Java_2주차  (0) 2023.10.12