본문 바로가기

Java/Java

(JAVA) 쓰레드의 실행제어 - join()

join()

쓰레드 자신이 하던 작업을 잠시 멈추고 다른 쓰레드가 지정된 시간 동안 작업을 수행하도록 할 때 사용한다.

 

간단한 GC 구현

  • 현재 사용할 수 있는 메모리 양이 현재 요구되는 메모리 양보다 작을 때
  • 현재 사용할 수 있는 메모리 양이 전체 메모리 양의 40 프로보다 작을 때
  • gc를 호출하여 가용 메모리를 줄인다.

threadjoinwithgc_1 쓰레드는 10초간 sleep 한다.

 

public class threadjoinwithgc {
    public static void main(String[] args) {
        threadjoinwithgc_1 th1 = new threadjoinwithgc_1();
        th1.setDaemon(true);
        th1.start();

        int requiredMemory = 0;

        for (int i=0;i<20;i++) {
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//            }
            requiredMemory = (int) ((Math.random() * 10) * 20);

            if(th1.freeMemory() < requiredMemory || th1.freeMemory() < th1.totalMemory() * 0.4 ) {
                th1.interrupt();
            }
            th1.usedMemory += requiredMemory;
            System.out.println("usedMemory : "+th1.usedMemory);
        }
    }
}
class threadjoinwithgc_1 extends Thread {
    final static int MAX_MEMORY = 1000;

    int usedMemory = 0;
    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(1000*10);
            } catch (InterruptedException e) {
                System.out.println("Awaken by interrupt");
            }
            gc();
            System.out.println("GC free memory :: "+freeMemory());
        }
    }
    public void gc() {
        usedMemory -=300;
        if (usedMemory<0) usedMemory = 0;
    }
    public int totalMemory() {return MAX_MEMORY;}
    public int freeMemory() {return MAX_MEMORY - usedMemory;}
}

실행결과

실행결과를 보면 interrupt()를 발생시켰음에도 불구하고 usedMemory 양이 1000이 넘는다.

이유는 gc()가 수행되기 이전 main 쓰레드의 작업이 수행되었기 때문이다. 

gc가 작업할 시간을 어느 정도 줘야 한다는 결론이 나온다.

이때 사용해야 할 것이 join()이다.

 

for (int i=0;i<20;i++) {
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//            }
    requiredMemory = (int) ((Math.random() * 10) * 20);

    if(th1.freeMemory() < requiredMemory || th1.freeMemory() < th1.totalMemory() * 0.4 ) {
        th1.interrupt();
        try {
            th1.join(100);
        } catch (InterruptedException e) {
        }
    }
    th1.usedMemory += requiredMemory;
    System.out.println("usedMemory : "+th1.usedMemory);
}

join을 이용해 gc가 수행하기 위한 0.1초 간의 시간을 주었다.

 

interrupt와 join은 같이 사용하는 것이 좋다는 것이 결론이다.

 

 


코드 참조

https://github.com/mike6321/PURE_JAVA/tree/master/Thread

 

mike6321/PURE_JAVA

Contribute to mike6321/PURE_JAVA development by creating an account on GitHub.

github.com