본문 바로가기
컴퓨터과학

동기(sync)/비동기(async) , 블로킹(blocking)/논블로킹(nonblocking) 쉽게 이해하고 완전 정복 하자 with 예제코드 with java

by 디찌s 2024. 5. 8.
728x90
반응형

 

 

 

 

 

예전에 공부했는데 다시보면 헷갈리는 동기,비동기, 블로킹,논블로킹에 대해 마스터 하겠다고 생각하고

정리한내용을 적어봅니다.

 

동기(Sync) Vs 블록킹(Blocking)

일단 제목만 봐도 두개가 다른 개념이라는것을 알수있다. 한번 정의를 내려보자

 

동기(Sync):

작업들이 순차적으로 실행되고, 다음 작업은 이전 작업이 완료될 때까지 기다립니다. 이는 여러 작업들이 순서대로 진행되는 것을 의미합니다.

블로킹(Blocking):

한 작업이 완료될 때까지 다른 작업을 멈추고 대기하는 것을 의미합니다. 보통 입출력 작업이나 네트워크 호출과 같은 I/O 작업에서 발생합니다.

 

두개의 개념은 비슷하면서도 다른의미를 가지고 있다. 즉, 동기적 작업은 순서대로 실행되지만, 블로킹이 발생할 수도 있고 발생하지 않을 수도 있다. 이제 이를 코드로 구현해보겠다.

 

내가볼땐 언어를 해석하는 능력에따라 이해가 어려울거같긴하다.. 나도 계속보다보니 아 ~ 그렇구나 하고 이해가됬다.

 

Sync만 존재할경우의 코드 예제

public class SyncNonBlockingExample {
    public static void main(String[] args) {
        // Task 1
        System.out.println("Task 1 Started");
        doSomeTask();
        System.out.println("Task 1 Completed");

        // Task 2
        System.out.println("Task 2 Started");
        System.out.println("Task 2 Completed");
    }

    public static void doSomeTask() {
        // Task Implementation
        // 실제로 블로킹되지 않는 작업 (예: 연산)
        for (int i = 0; i < 5; i++) {
            System.out.println("Doing some task in Task 1..."); // 작업을 시뮬레이션하기 위해 출력만 함
        }
    }
}

 

위 코드에서 doSomeTask() 메서드는 작업을 시뮬레이션하기 위해 반복문을 사용하고 있다. 이 반복문은 실제로는 블로킹되지 않는 작업을 수행합니다. 따라서 Task 1은 동기적으로 실행되지만 블로킹이 발생하지 않습니다.

 

동기(Sync)와 Blocking의 결합 코드 예제 

public class SyncBlockingExample {
    public static void main(String[] args) {
        // Task 1
        System.out.println("Task 1 Started");
        doSomeTask();
        System.out.println("Task 1 Completed");

        // Task 2
        System.out.println("Task 2 Started");
        try {
            TimeUnit.SECONDS.sleep(3); // Task 2를 3초간 블로킹
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Task 2 Completed");
    }

    public static void doSomeTask() {
        // Task Implementation
        try {
            Thread.sleep(2000); // 예시를 위해 2초 동안 대기
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 

위 코드에서는 Task 1이 실행되면서 doSomeTask를 실행할때 블록킹이 발생 그후  3초간 Task 2가 블로킹되었습니다. 따라서 Task 2는 Task 1이 완료된 후에 실행됩니다.

즉, 블로킹은 스레드가 멈춘후 대기한다고 보면 될거같고, 동기작업은 이전작업이 완료되어야 진행한다고 생각하면 될거같다.

 

 

 

비동기(Async) Vs 논블록킹(Non-Blocking)

 

비동기(Asynchronous)와 논블로킹(Non-blocking)은 밀접한 관련이 있지만 서로 다른 개념입니다.

 

 

비동기(Asynchronous)

비동기 작업은 한 작업의 완료 여부와 상관없이 다른 작업을 동시에 수행할 수 있는 것을 의미합니다. 이는 보통 Callback 함수, Future/Promise, 또는 async/await와 같은 메커니즘을 사용하여 구현됩니다.

 

논블로킹(Non-blocking)

논블로킹은 한 작업이 다른 작업의 완료를 기다리지 않고 바로 실행될 수 있는 것을 의미합니다. 이는 I/O 작업이나 네트워크 호출과 같은 작업에서 특히 중요합니다. 논블로킹 작업은 작업이 완료될 때까지 계속해서 진행됩니다.

 

 

비동기만 존재하는 코드 예제

public class AsyncExample {
    public static void main(String[] args) {
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            System.out.println("Task Started");
            doSomeTask();
            System.out.println("Task Completed");
        });

        System.out.println("Main Thread continues...");

        // 비동기 작업이 완료될 때까지 기다림
        future.join();
    }

    public static void doSomeTask() {
        // Task Implementation
        try {
            Thread.sleep(2000); // 예시를 위해 2초 동안 대기
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

이 예제에서는 CompletableFuture를 사용하여 비동기 작업을 수행하고 있습니다. 메인 스레드는 비동기 작업이 완료될 때까지 기다립니다. 그러나 비동기 작업이 백그라운드에서 실행되므로 메인 스레드는 다른 작업을 수행할 수 있습니다. 하지만 이 코드에서는 블로킹이 발생합니다.

 

비동기 논블로킹이 같이 존재하는 코드예제 

public class AsyncNonBlockingExample {
    public static void main(String[] args) {
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            System.out.println("Task Started");
            doSomeTask();
            System.out.println("Task Completed");
        });

        System.out.println("Main Thread continues...");

        // 비동기 작업이 완료될 때까지 기다리지 않음
        // future.join(); // 주석처리하여 비동기 논블로킹 작업으로 변경

        // 추가 작업
        System.out.println("Additional Work while waiting for async task...");

        // 비동기 작업이 완료되었는지 확인하고 처리
        while (!future.isDone()) {
            // 비동기 작업이 완료될 때까지 기다리지 않고 다른 작업 수행
            System.out.println("Doing some other work...");
        }

        System.out.println("Async Task has been completed!");
    }

    public static void doSomeTask() {
        // Task Implementation
        try {
            Thread.sleep(2000); // 예시를 위해 2초 동안 대기
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 

이 예제에서는 메인 스레드가 비동기 작업이 완료될 때까지 기다리지 않고 계속해서 다른 작업을 수행합니다. future.join()을 주석 처리하여 비동기 논블로킹 작업을 시뮬레이션합니다. 이때 while 루프를 사용하여 비동기 작업이 완료될 때까지 주기적으로 상태를 확인합니다.

728x90
반응형

댓글