본문 바로가기

Language/Java

시간 간격을 정확하게 측정하는 방법.

반응형

개발을 하다 보면 시간 간격을 두어야 하는 경우가 많다.

일반적으로 Thread.Sleep 함수를 사용하는데 이 방법은 Thread 상태에 따라 오차가 존재한다.

        private void measureTime()
        {
            while (true)
            {
                long currentTimeMills = System.currentTimeMillis();
                try
                {
                    Thread.sleep(100);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                long itv = System.currentTimeMillis() - currentTimeMills;
                System.out.println(itv);
            }
        }

0.1초 간격으로 콘솔을 출력했지만 0.004~0.012초까지의 오차가 발생한다.

이정도면 정확하다고 생각할 수 있지만 타이머를 개발한다고 가정하면 이 오차는 생각보다 크다.

타이머를 1분 동안 실행시켰다고 했을 때 오차 범위는  600 * 0.004 = 2.4초밖에 안되지만

1시간을 실행시켰을 때 2.4 * 60 = 144초의 오차가 발생할 수 있다.

실행시간이 크면 클 수록 오차 범위는 걷잡을 수 없이 커진다.

 

그렇다면 어떻게 해야 정확한 시간을 측정할 수 있을까?

여러 가지 방법이 있을 수 있지만 가장 간단한 방법은 타이머 전용 쓰레드를 생성하고 무한 루프를 실행하면서 간격을 계산 하는 방법이다.

        private void measureTime()
        {
            long prevTimeMills = System.currentTimeMillis();
            while (isRunning)
            {
                long currentTimeMills = System.currentTimeMillis();
                long itv = currentTimeMills - prevTimeMills;
                if (itv >= 100)
                {
                    prevTimeMills = currentTimeMills;
                    System.out.println(currentTimeMills + ":" + itv);
                }
            }
        }

정확하게 0.1초 간격이 찍히는 걸 확인할 수 있다. 이 방법도 100% 정확하다고 할 수 는 없는게 10분 정도 돌렸을 때 0.001초 정도의 차이가 발생하기는 한다.

Thread.Sleep 방식보다 오차 범위가 현저하게 줄어드는 장점이 있지만 스레드를 무한 루프로 돌리기 때문에 멀티쓰레드 환경에서만 가능한 방법이며 남발하게 되면 CPU에 과부하를 줄 수 있다.

반응형

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

합집합, 교집합, 차집합 ArrayList로 구현해보기  (0) 2021.04.29
Java로 자료구조(LinkedList, Stack, Queue) 구현해보기  (0) 2021.04.26
자바 == 연산자  (0) 2021.04.12
제네릭(Generic)  (0) 2021.04.02
Interface Comparable  (0) 2020.11.29