레알윙 2020. 7. 20. 13:04
반응형

Callable

  • Runnable과 유사하지만 작업의 결과를 받을 수 있다.

 

 

Future

 

get() - 결과를 가져오기

  • 블록킹 콜
    • 결과를 가져올때까지 기다린다.
  • 타임아웃(최대한으로 기다릴 시간)을 설정 가능
public class App {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		ExecutorService executorService = Executors.newSingleThreadExecutor();
		Future<String> helloFuture = executorService.submit(() -> {
			Thread.sleep(2000L);
			return "Callable";
		});
		System.out.println("Hello");
		String result = null;
		result = helloFuture.get();
		helloFuture.get(); //블록킹콜
		
		System.out.println(result);
		executorService.shutdown();
	}
}

 

 

작업 상태 확인하기 isDone()

  • 완료 했으면 true 아니면 false를 리턴한다.
public class App {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		ExecutorService executorService = Executors.newSingleThreadExecutor();
		
		Callable<String> hello = () -> {
			Thread.sleep(2000L);
			return "Hello";
		};
		
		Future<String> helloFuture = executorService.submit(hello);
		System.out.println(helloFuture.isDone());
		System.out.println("Startd!");
		
		helloFuture.get(); //블록킹콜
		
		System.out.println(helloFuture.isDone());
		System.out.println("End!");
		executorService.shutdown();
	}
}

 

 

작업 취소하기 cancel()

  • 취소 했으면 true 못했으면 false를 리턴한다.
  • parameter로 true를 전달하면 현재 진행중인 쓰레드를 interrupt하고 그러지 않으면 현재 진행중인 작업이 끝날때까지 기다린다.
public class App {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		ExecutorService executorService = Executors.newSingleThreadExecutor();
		
		Callable<String> hello = () -> {
			Thread.sleep(2000L);
			return "Hello";
		};
		
		Future<String> helloFuture = executorService.submit(hello);
		System.out.println(helloFuture.isDone());
		System.out.println("Startd!");
		
		helloFuture.cancel(false);
		
		//아래의 isdone은 위에서 cancel을 했기 때문에 값을 가져오는 것
		System.out.println(helloFuture.isDone()); 
		System.out.println("End!");
		executorService.shutdown();
	}
}

 

위의 코드에서 cancel 끝나고 isDone으로 가져오게 되면 아래와같은 오류가 발생이된다.

발생 이유는 종료가 되었기 때문이다.

 

 

 

여러 작업 동시에 실행하기 invokeAll()

  • 동시에 실행한 작업 중에 제일 오래 걸리는 작업 만큼 시간이 걸린다.
    • 모든 결과가 나올때까지 기다린다.
public class App {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		ExecutorService executorService = Executors.newSingleThreadExecutor();

		Callable<String> hello = () -> {
			Thread.sleep(2000L);
			return "Hello";
		};

		Callable<String> java = () -> {
			Thread.sleep(2000L);
			return "java";
		};

		Callable<String> jinSeok = () -> {
			Thread.sleep(2000L);
			return "jinSeok";
		};

		List<Future<String>> futures = executorService.invokeAll(Arrays.asList(hello, java, jinSeok));
		for(Future<String> f : futures) {
			System.out.println(f.get());
		}

		executorService.shutdown();
	}
}

 

 

 

 

여러 작업 중에 하나라도 먼저 응답이 오면 끝내기 invokeAny()

  • 동시에 실행한 작업 중에 제일 짧게 걸리는 작업 만큼 시간이 걸린다.
  • 블록킹 콜이다.
public class App {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		ExecutorService executorService = Executors.newFixedThreadPool(4);

		Callable<String> hello = () -> {
			Thread.sleep(2000L);
			return "Hello";
		};

		Callable<String> java = () -> {
			Thread.sleep(3000L);
			return "java";
		};

		Callable<String> jinSeok = () -> {
			Thread.sleep(1000L);
			return "jinSeok";
		};

		String s = executorService.invokeAny(Arrays.asList(hello, java, jinSeok));
		System.out.println(s);

		executorService.shutdown();
	}
}

 

 

 

단, 싱글 쓰레드로 할경우 먼저 들어간 순서대로 나오게된다.

반응형