[JAVA] Executor 인터페이스

Executor 인터페이스는 명시적으로 스레드를 생성하는 대신에 사용됩니다. 일반적으로 호출자 스레드가 아닌 다른 스레드에서 실행이 됩니다.

Executor 인터페이스는 스레드를 관리하고 작업을 스레드에 할당하는 기본적인 인터페이스입니다.

Executor는 작업 실행 및 관리를 담당하며, 다양한 작업 큐 및 스레드 풀 구현을 허용하여 애플리케이션에서 비동기적으로 작업을 수행할 수 있게 해줍니다.

 

Executor 기본 예시

public class Main {

	public static void main(String[] args) {
		Task task = new Task();
		for(int i = 0; i < 10 ; i++) {
			task.execute(new RunThread());
		}
	}
	
	static class Task implements Executor {
		@Override
		public void execute(Runnable command) {
			new Thread(command).start();			
		}
	}
	
	static class RunThread implements Runnable {
		@Override
		public void run() {
			System.out.println("thread name:" + Thread.currentThread().getName());
		}
		
	}
}

Executor 인터페이스를 구현하는 클래스에서 execute 메서드를 구현하여 작업을 스레드에 전달하고 실행합니다. 비동기적으로 작업을 실행합니다.

 

Executor 순차적 실행 예시

public class Main2 {

	public static void main(String[] args) {
		Executor executor = Runnable::run;
		SerialExecutor serialExecutor = new SerialExecutor(executor);
		
		Runnable task1 = () -> System.out.println("task 1 run");
		Runnable task2 = () -> System.out.println("task 2 run");
		Runnable task3 = () -> System.out.println("task 3 run");
		
		serialExecutor.execute(task1);
		serialExecutor.execute(task2);
		serialExecutor.execute(task3);
	}
	
	static class SerialExecutor implements Executor {
		final Queue<Runnable> tasks = new ArrayDeque<>();
		final Executor executor;
		Runnable active;
		
		SerialExecutor(Executor executor) {
			this.executor = executor;
		}

		@Override
		public synchronized void execute(final Runnable command) {
			tasks.offer(new Runnable() {
				
				@Override
				public void run() {
					try {
						command.run();
					} finally {
						nextTask();
					}
				}
			});
			
			if(active == null) nextTask();
			
		}
		
		protected synchronized void nextTask() {
			if((active = tasks.poll()) != null) {
				executor.execute(active);
			}
		}
		
	}
}

큐를 이용하여 작업을 관리하고 순차적으로 실행하게 합니다. Executor를 통해서 실제 작업을 하고 Runnable를 통해서 현재 실행 중인 작업을 나타냅니다.