본문 바로가기
Spring/Spring Study

[Spring Thread Pool 사용하기

by ♡˖GYURI˖♡ 2024. 4. 8.
@Component
public class TestScheduler {
	
    @Scheduled(fixedDelay = 1000)   //작업이 끝나는 시점으로부터 1초 후에 수행
    public void test1() throws InterruptedException {
    	Thread.sleep(10000);      // 10초 대기
        System.out.println("Test1: " + LocalDateTime.now());
        
    }
    
    @Scheduled(fixedDelay = 1000)   //작업이 끝나는 시점으로부터 1초 후에 수행
    public void test2() {
        System.out.println("Test2: " + LocalDateTime.now());   
    }
}

 

위 코드를 보았을 때 test1이 한 번 실행될 때 test2는 10번 실행될 것으로 보이지만 실제 결과는 그렇지 않다.

콘솔을 보면 test1의 작업이 종료되어야지만 test2의 작업이 실행될 것이다.

그래서 test2의 경우에는 작업 대기가 없지만 test1과 함께 10초에 한 번씩 작업이  실행된다.

 

이유는 바로 스케줄러가 1개의 쓰레드로 동작하고 있기 때문이다.

이는 쓰레드를 늘리는 것으로 해결할 수 있다. 

 

 

Thread Pool

Thread Pool은 여러 개의 쓰레드를 유지하고 관리하기 위해 사용된다.

쓰레드는 한 번 생성시키고 소멸하면 굉장히 많은 리소스를 소모하게 되기 때문에 매번 쓰레드를 생성시키고 없애기 보다는 Thread Pool에서는 설정된 크기의 쓰레드를 만들어 놓고 해당 쓰레드들을 계속해서 재사용할 수 있도록 관리한다.

 

 

적정 사이즈

  • 쓰레드가 너무 많을 경우 : 메모리 낭비
  • 쓰레드가 너무 적을 경우 : 효율성 저하

쓰레드 개수는 코드로 고정시키기 보다는 서비스가 실행되는 CPU의 코어 개수에 따라 유동적으로 생성될 수 있도록 해주는 것이 좋다.

 

  • CPU 처리가 많은 경우 : CPU의 코어를 N개라고 했을 때, N + 1만큼의 쓰레드를 생성해주면 최적에 가까운 성능을 낼 수 있다고 봄
  • I/O 작업이 많은 경우 : N * 2만큼의 쓰레드를 생성해주기도 함

단순히 많이 생성하기보다는 어떤 작업을  처리하느냐가 기준이 된다.

 

@Configuration
public class SchedulerConfig implements SchedulingConfigurer {

	@Override
	public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            // Thread Pool 설정
            ThreadPoolTaskScheduler threadPool = new ThreadPoolTaskScheduler();  

            // Thread 개수 설정
            int n = Runtime.getRuntime().availableProcessors();
            threadPool.setPoolSize(n);
            threadPool.initialize();

            taskRegistrar.setTaskScheduler(threadPool);
	}
}

 

이렇게 설정을 바꿔주면 test2는 1초에 한 번씩 실행되고 test1은 10초에 한 번씩 실행될 것이다.

 

 

 

 

 


 

 

[Spring] Thread Pool 사용하기(feat. Scheduler)

앞의 글에서 스프링에서 스케줄링 하는 내용을 다뤘는데, 스케줄링으로 실행되어야 할 기능이 여러개 일 경우에는 한 가지 더 고려해야하는 것이 있다.바로 Thread Pool이다.위의 코드를 봤을 땐 te

velog.io