본문 바로가기
카테고리 없음

비동기(asynchronous)와 병렬(parallel)

by 뿌랭랭 2023. 5. 4.

비동기(asynchronous)와 병렬(parallel)은 모두 동시에 여러 작업을 처리할 수 있는 개념이지만, 그 방식에는 차이가 있습니다.

 

비동기는 작업이 요청되면 결과를 기다리지 않고 다음 작업을 수행하며, 결과가 나중에 도착하면 그때 처리합니다. 이를 일종의 '요청-응답' 방식으로 처리합니다. 예를 들어, 웹 서버에서 클라이언트가 요청한 데이터를 비동기 방식으로 처리하면, 서버는 다른 요청을 동시에 처리하면서 해당 데이터를 응답합니다.

 

반면에 병렬은 여러 작업을 동시에 처리하는 것을 의미합니다. 병렬 처리를 하면 여러 개의 작업을 더 빠르게 처리할 수 있습니다. 예를 들어, 데이터를 병렬 처리하여 여러 스레드나 프로세스를 사용해 데이터를 동시에 처리하면 처리 시간을 단축시킬 수 있습니다.

요약하면, 비동기는 작업이 요청되었을 때 다른 작업을 수행하면서 결과를 기다리는 방식이고, 병렬은 여러 작업을 동시에 처리하는 방식입니다.

 

 

그럼 비동기 개념 안에 병렬이 들어가는건가?

비동기와 병렬은 동시성(concurrency)을 다루는 두 가지 다른 개념입니다. 동시성은 여러 작업을 동시에 처리하는 것을 의미하는데, 이는 동시성을 구현하는 방식에 따라 비동기와 병렬로 나뉠 수 있습니다.

 

비동기는 작업이 요청되면 다른 작업을 수행하면서 해당 작업의 결과를 기다리지 않고, 나중에 결과가 도착했을 때 처리합니다. 이 때, 여러 개의 비동기 작업을 동시에 처리할 수 있습니다. 그러나 비동기 작업은 실제로는 하나의 스레드에서 순차적으로 처리되기 때문에, 이 경우에는 병렬 처리가 이루어지지 않습니다.

 

반면에, 병렬은 여러 개의 작업을 동시에 처리하는 것을 의미합니다. 병렬 처리는 다수의 스레드나 프로세스를 이용해 작업을 분할하고 각각의 작업을 동시에 처리하는 방식으로 이루어지기 때문에, 병렬 처리는 비동기 작업보다 더 많은 리소스를 필요로 합니다.

따라서, 비동기와 병렬은 서로 다른 개념이지만, 비동기 처리에서는 병렬 처리를 할 수도 있습니다. 그러나 비동기 처리에서 병렬 처리가 이루어지는 경우는 한정적이며, 이 경우에는 여러 개의 스레드나 프로세스를 사용해 작업을 동시에 처리합니다.

 

 

CompletableFuture 는 비동기인데 병렬 사용하나?

CompletableFuture는 Java 8에서 추가된 비동기적인 프로그래밍을 지원하는 클래스입니다. CompletableFuture는 비동기 작업을 수행하면서, 다른 작업을 병렬로 처리하는 것도 가능합니다.

 

CompletableFuture의 supplyAsync나 runAsync 메서드는 작업을 비동기적으로 실행하며, 기본적으로는 하나의 스레드에서 순차적으로 실행됩니다. 그러나 이 메서드들은 두 번째 인자로 Executor를 지정할 수 있습니다. Executor를 지정하면 해당 Executor가 제공하는 스레드 풀에서 작업이 병렬적으로 실행됩니다.

 

예를 들어, 다음과 같이 CompletableFuture를 사용하여 Executor를 지정하여 작업을 병렬로 실행할 수 있습니다.

 

Executor executor = Executors.newFixedThreadPool(10);
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
// 작업
return 42;
}, executor);

 

위 코드에서 newFixedThreadPool(10)는 10개의 스레드를 가진 스레드 풀을 생성합니다. supplyAsync 메서드는 이 스레드 풀에서 작업을 실행합니다. 따라서 이 작업은 10개의 스레드 중 하나에서 실행됩니다.

결론적으로, CompletableFuture는 비동기 작업을 수행하면서, Executor를 사용하여 병렬적으로 작업을 실행할 수 있습니다. 이는 CompletableFuture가 비동기적인 동시성과 병렬성을 모두 지원한다는 것을 의미합니다.

 

runAsync 가 왜 기본적으로 하나의 스레드에서 순차적으로 실행되? 병렬아니야?

 

runAsync 메서드는 CompletableFuture에서 비동기적으로 작업을 실행하는 메서드 중 하나입니다. 기본적으로 runAsync 메서드는 호출한 스레드에서 실행되며, 이 경우에는 하나의 스레드에서 순차적으로 실행됩니다.

 

이는 runAsync 메서드를 호출한 스레드가 현재 실행되고 있는 스레드이기 때문입니다. 즉, runAsync 메서드를 호출한 스레드가 main 스레드인 경우에는 runAsync에서 실행되는 작업도 main 스레드에서 순차적으로 실행됩니다.

 

하지만, runAsync 메서드는 두 번째 인자로 Executor를 지정하여 병렬 실행할 수 있습니다. Executor를 지정하면 해당 Executor에서 작업을 실행하므로, 병렬 처리가 가능해집니다.

 

따라서, runAsync 메서드는 기본적으로 순차적으로 실행되지만, Executor를 지정하여 병렬 실행할 수 있습니다. runAsync 메서드의 병렬 실행은 Executor가 제공하는 스레드 풀에서 작업이 병렬적으로 실행됩니다.