Notice
Recent Posts
Recent Comments
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

충분히 쌓여가는

join(), yield() 본문

Java/JAVA3

join(), yield()

빌드이너프 2023. 8. 7. 10:46

join()

지정된 시간동안 특정 쓰레드가 작업하는 것을 기다린다

void join() // 작업이 모두 끝날 때까지
void join(long millis) // 천 분의 일 초 동안
void join(long millis, int nanos) // 천 분의 일 초 + 나노 초 동안

 

예외처리를 해야한다(InterruptedException이 발생하면 작업 재개)

public staic void main(String args[]) {
    ThreadTest_1 th1 = new ThreadTest_1();
    ThreadTest_2 th2 = new ThreadTest_2();
    th1.start();
    th2.start();
    startTime = System.currentTimeMillis();
    
    try {
        th1.join() // main 쓰레드가 th1의 작업이 끝날 때까지 기다린다
        th2.join() // main 쓰레드가 th2의 작업이 끝날 때까지 기다린다
    } catch(InterruptedException e) {}
    
    System.out.print("소요시간: " + (System.currentTimeMillis() - ThreadTest.startTime));
}

 

코드

class ThreadTest {
    static long startTime = 0;

    public static void main(String args[]) {
        ThreadTest_1 th1 = new ThreadTest_1();
        ThreadTest_2 th2 = new ThreadTest_2();
        th1.start();
        th2.start();
        startTime = System.currentTimeMillis(); // 시작시간

        try {
            th1.join();	// main쓰레드가 th1의 작업이 끝날 때까지 기다린다.
            th2.join();	// main쓰레드가 th2의 작업이 끝날 때까지 기다린다.
        } catch(InterruptedException e) {}

        System.out.print("소요시간:" + (System.currentTimeMillis() - ThreadTest.startTime));
    }
}

class ThreadTest_1 extends Thread {
    public void run() {
        for(int i=0; i < 300; i++) {
            System.out.print(new String("-"));
        }
    }
}

class ThreadTest_2 extends Thread {
    public void run() {
        for(int i=0; i < 300; i++) {
            System.out.print(new String("|"));
        }
    }
}

 

 

join() 예시

public void run() {
    while(true) {
        try {
            Thread.sleep(10 * 1000); // 10초를 기다린다
        } catch(InterruptedException e) {
            System.out.println("Awaken by interrupt()");
        }
        
        gc(); // garbage collcetion을 수행한다
        System.out.println("Garbage Collceted. Free Momory" + freeMemory());
    }
}

 

for(int i=0; i<20; i++) {
    // 필요한 메모리가 사용할 수 있는 양보다 적거나 전체 메모리의 60%이상 사용했을 경우 gc를 깨운다
    requiredMemory = (int)(Math.random() * 10) * 2);
    if(gc.freeMemory() < requiredMemory || gc.freeMemory() < gc.totalMemory() * 0.4) {
        gc.inrerrupt() // 잠자고 있는 쓰레드 gc를 깨운다
        
        try {
            gc.join(100); // 0.1초
        } catch(InterruptedException e) {}
    }
    gc.usedMemory += requiredMemory;
    System.our.println("usedMemory: " + gc.usedMemory);
}

 

yield()

남은 시간을 다음 쓰레드에게 양보하고, 자신(현재 쓰레드)은 실행대기한다

static 메서드이기 때문에 쓰레드 자기 자신한테만 사용 가능

 

yield()와 interrupt()를 적절히 사용하면, 응답성과 효율을 높일 수 있다

class ThreadTest implements Runnable {
    boolean suspended = false;
    boolean stopped = false;
    
    Thread th;
    
    ThreadTest(String name) {
        th = new Thread(this, name);
    }
    
    public void run() {
        while(!stopped) {
            if(!suspended) {
                /*
                    작업 수행
                */
                try {
                    Thread.sleep(1000);
                } catch(InterruptedException e) {}
            } else {
                Thread.yield();
            }
        }
    }
}

 

public void start() {[
    th.start();
}

public void resume() {[
    suspended = false;
}

public void suspend() {[
    suspended = true;
    th.interrupt();
}

public void stop() {[
    stopped = true;
    th.interrupt();
}

'Java > JAVA3' 카테고리의 다른 글

wait()와 notify()  (0) 2023.08.08
쓰레드의 동기화(synchronization)  (0) 2023.08.07
suspend(), resume(), stop()  (0) 2023.08.07
sleep(), interrupt()  (0) 2023.08.04
데몬 쓰레드(daemon thread), 쓰레드의 상태  (0) 2023.08.03