본문 바로가기

Language/Java / JSP

[Java] 주기적인 실행(ScheduledThreadPoolExecutor)

반응형

기존 포스팅에서 프로그램의 일시정지라고 할수 있는 스레드 sleep에 대해 설명한 적이 있다.
당시 sleep을 잘 이용하면 while 문과 같은 반복문을 통해 스케줄링 처럼 주기적으로 특정 로직을 실행할 수 있다고 하였는데,
해당 포스팅 끝에서도 밝혔듯이 사실 sleep과 while을 이용한 반복적인 작업은 사실 맞지 않다.

해상 프로세스를 계속 실행시켜둔 상태에서 반복적이고 주기적인 일을 할때에는 오히려 Timer 등을 이용하는게 좋은데, 오늘은
Timer가 아닌 ScheduledThreadPoolExecutor를 이용하여 특정시간 간격으로 반복적인 로직을 처리해 보자.

ScheduledThreadPoolExecutor는 ThreadPoolExecutor라는 이름에서 보이듯이 병렬처리를 위한 스레드 executor 라고 할 수 있는데, 멀티 스레드 사용에 대해 고민해봤던 사람이라면 대충 무엇인지는 알 수 있을것이다. (자세한 설명은 생략..... ㅡ_ㅡ)

Timer와 ScheduledThreadPoolExecutor가 가장 큰 차이는 멀티 스레드를 지원하느냐 여부라고 할 수 있다.(적어도 본인 생각)
ScheduledThreadPoolExecutor는 싱글/멀티 스레드 모두 사용할 수 있기 때문에 나같은 경우 Timer보다 많이 사용하는 편이다.


아래 예제는 3초 간격으로 특정 로직을 처리하는 예제이다. 간단하니 소스만 봐도 쉽게 이해가 갈것이다.

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class ScheduleExecTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		
		// 실행간격 지정(3초)
		int sleepSec = 3 ;
		
		// 시간 출력 포맷
		final SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss");

		
		// 주기적인 작업을 위한 
		final ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
		
		
		exec.scheduleAtFixedRate(new Runnable(){
			
			public void run(){
				try {

					Calendar cal = Calendar.getInstance() ;
					
					
					// 콘솔에 현재 시간 출력
					System.out.println(fmt.format(cal.getTime())) ;
					
				} catch (Exception e) {
					
					e.printStackTrace();
					
					
					// 에러 발생시 Executor를 중지시킨다
					exec.shutdown() ;
				}
			}
		}, 0, sleepSec, TimeUnit.SECONDS);
	}

}


사실 sleep등을 이용한 반복 처리는 특정 로직이 끝나는 시간과 무관하게 설정한 시간 그대로 정지 된다는 것이다.
하지만 ScheduledThreadPoolExecutor를 사용할 경우 로직의 종료시간을 계산하여 설정한 시간만큼 빼고 실행되므로 특정 시간에 맞춰 무엇인가를 해야하는 스케줄링 작업에 더 용이하다.

끝으로 주기적이고 반복적인 작업은 sleep, Timer, ScheduledThreadPoolExecutor 등 여러 방법등을 사용할 수 있는데, 요구사항에 맞는 부분을 적절하게 선택하여 사용하는게 좋다.