보통 프로그래밍을 하면 동기프로그램을 짜게 됩니다. HelloWorld와 같은 sample 코드들 말입니다. Main 함수에서 호출되는 다른 함수들을 생각해 보세요.

public class HelloWorld {

public static void main(String[] args) {
HelloWorld helloWorld = new HelloWorld();
System.out.println(helloWorld.sayHello());
}

public String sayHello() {
return "Hello!";
}
}

sayHello()함수가 호출되고 있고 이 함수는 string을 return하고 있습니다. 아주 짧은 순간이긴 하지만 sayHello()가 실행되는 순간에는 main함수는 멈추고 return되기를 기다리고 있는 것입니다. 다음 예를 보시면 이해가 빠르실 겁니다.

동기식

public class HelloWorld {
static long start;

public static void main(String[] args) throws InterruptedException{
HelloWorld helloWorld = new HelloWorld();
System.out.println("[" + System.currentTimeMillis() + "]" + "Start!");
System.out.println(helloWorld.sayHello());
System.out.println("[" + System.currentTimeMillis() + "]" + "End!");
}

public String sayHello() throws InterruptedException{
System.out.println("[" + System.currentTimeMillis() + "]calling sayHello()");
Thread.sleep(1000);
System.out.println("[" + System.currentTimeMillis() + "]end sayHello()");
return "[" + System.currentTimeMillis() + "]" + "HelloWorld!";
}
}
[1552890046994]Start!
[1552890046994]calling sayHello()
[1552890047994]end sayHello()
[1552890047994]HelloWorld!
[1552890047994]End!

비동기식

public class HelloWorld {
static long start;

public static void main(String[] args) throws InterruptedException, ExecutionException {
HelloWorld helloWorld = new HelloWorld();
Future<String> hello;
System.out.println("[" + System.currentTimeMillis() + "]" + "Start!");
hello = helloWorld.getSayHelloAsync();
System.out.println("[" + System.currentTimeMillis() + "]" + "End!");
System.out.println(hello.get());
}

public String sayHello() throws InterruptedException{
System.out.println("[" + System.currentTimeMillis() + "]calling sayHello()");
Thread.sleep(1000);
System.out.println("[" + System.currentTimeMillis() + "]end sayHello()");
return "[" + System.currentTimeMillis() + "]" + "HelloWorld!";
}

public Future<String> getSayHelloAsync(){
CompletableFuture<String> future = new CompletableFuture<>();
new Thread(()-> {
try {
String result = sayHello();
future.complete(result);
} catch (Exception e) {
future.completeExceptionally(e);
}
}).start();
return future;
}
}
[1552891812467]Start!
[1552891812526]End!
[1552891812526]calling sayHello()
[1552891813526]end sayHello()
[1552891813526]HelloWorld!

여기에서 중요한건 sayHello()의 결과를 얻어오는 타이밍입니다. 동기식은 main함수의 3줄 sayHello()가 실행되어야 "End!"가 프린트 되는 반면, 비동기식은 getSayHelloAsync()가 실행되고 바로 "End!"가 출력되고나서 결과를 가져옵니다.

한마디로 Synchronous/Asynchronous는 호출되는 함수의 호출에 따른 결과를 언제 받느냐에 따라 구분이 됩니다. 

함수를 호출했을 때 바로 결과를 주기로 한 방식은 Synchronous

함수를 호출했을 때 바로 결과를 받지않고 나중에 결과를 주기로 한 방식은 Asynchronous

이번에 Async와 Sync의 차이점에 대해서 알아 봤습니다. 다음 포스트에서는 Block과 Non-block에 대해서 알아보겠습니다. 참고로 block/non-block과 sync/async의 개념은 양립할 수 있는 개념이기에 sync/async도 비교 설명 하겠습니다.


+ Recent posts