[Java] Thread#6, 스레드 풀 예제 및 개념(Future 객체, execute(), submit())

스레드풀

- 병렬작업 처리가 많아지면 스레드 개수 증가 -> 스레드 생성 및 스케쥴링을 CPU가 바빠져서 메모리 많이 사용

- 결국 성능저하.

- 갑작스런 병렬 작업처리가 많아질 때 스레드풀을 이용.

- 스레드를 제한된 개수만큼 정해놓고 작업큐(Queue)에 들어오는 작업들을 하나씩 스레드가 맡아서 처리.

- 스레드풀 생성/사용을 위해 Executors 클래스와 ExecutorService 인터페이스를 제공.

- Executors의 다양한 정적메소드로 ExecutorService의 구현객체를 만들 수 있는데 이것이 바로 스레드풀.

 

스레드풀 생성

Executors 클래스

- newCachedThreadPool()

- newFixedThreadPool()

ExecutorService executorService = Executors.newCachedThreadPool();

ExecutorService executorService2 = Executors.newFixedThreadPool(
	Runtime.getRuntime().availableProcessors();
); //cpu의 코어수만큼 최대스레드풀 생성
스레드풀 종료

executorService.shutdown() - 남아있는 작업을 마무리하고 스레드풀 종료!

executorService.shutdownNow() - 남아있는 작업과는 상관없이 강제로 종료!

 

작업생성과 처리요청
작업생성

- 하나의 작업은 Runnable or Callable 구현 클래스로 표현한다.

- Runnable(무)과 Callable(유)의 차이는 리턴값의 유무이다.

Runnable task = new Runnable(){
	@Override
    public void run(){ /*스레드가 처리할 작업 내용*/ }
}

Callable<T> taskc = new Callable<T>(){
	@Override
    public T call() throws Exception{
    	//스레드가 처리할 작업 내용
		return T;
    }
}
작업처리요청

- ExecutorService의 작업큐에 Runnable 혹은 Callable객체를 넣는 행위!!

- 작업처리 요청을 위해 submit()과 execute() 메소드를 제공함.

- execute() : Runnable을 작업큐에 저장

- submit() : Runnable 또는 Callable을 작업큐에 저장, Future 객체를 리턴

- submit 메소드를 사용하는 것이 스레드의 생성오버헤드를 줄이는데 좋다. 왜냐하면 execute메소드는 작업처리중 예외가 발생하면 쓰던 스레드를 버리고 새로운 스레드를 생성한다. 하지만 submit 메소드는 쓰던 스레드를 재활용한다.

(이는 스레드이름을 통해 확인할 수 있다.)

public static void main(String[] args) throws Exception{
		ExecutorService executorService = Executors.newFixedThreadPool(2); //최대스레드 개수가 2인 스레드풀 생성
		
		for(int i =0; i<10; i++) {
			Runnable runnable = new Runnable() {

				@Override
				public void run() {
					ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService;
					int poolSize = threadPoolExecutor.getPoolSize();
					String threadName = Thread.currentThread().getName();
					System.out.println("[총 스레드 개수 : "+poolSize+"] 작업 스레드 이름 :"+threadName);
					
					//예외 발생시킴
					int value = Integer.parseInt("삼");
				}
			};	
            //이 두개를 번갈아가면서 실행해보세요.
			//executorService.execute(runnable);
			executorService.submit(runnable);
			
			Thread.sleep(10);//콘솔 출력시간을 위해 0.01초 일시정지
		}
		executorService.shutdown();
	}

댓글

Designed by JB FACTORY