Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

The Office Lover

Java blocking과 non-blocking 본문

Backend

Java blocking과 non-blocking

Michael Gary Scott 2023. 7. 21. 14:58

Java blocking과 non-blocking

Blocking I/O (블로킹 입출력)

Blocking I/O는 입출력 작업 중에 해당 작업이 완료될 때까지 스레드가 블로킹되는 방식입니다. 즉, 입출력 작업이 완료되기 전까지 해당 스레드는 다른 작업을 수행할 수 없으며 대기 상태에 있게 됩니다. 입출력 작업은 데이터를 읽어오거나 쓰는 동안 스레드가 멈추기 때문에 해당 작업이 오래 걸리는 경우, 다른 작업들의 처리도 지연될 수 있습니다. 

import java.io.*;

public class BlockingIOExample {
    public static void main(String[] args) {
        try {
            FileInputStream fileInputStream = new FileInputStream("input.txt");
            byte[] data = new byte[1024];
            int bytesRead = fileInputStream.read(data); // 데이터를 읽기 위해 블로킹됨
            System.out.println("Read " + bytesRead + " bytes: " + new String(data));
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

위 예시에서 'read()' 메서드가 데이터를 읽을 때까지 스레드가 블로킹되어 대기합니다. 

 

 

 

 

 

 

 

Non-blocking I/O (논블로킹 입출력)

Non-blocking I/O는 입출력 작업 중에 스레드가 블로킹되지 않고 계속 다른 작업을 수행할 수 있는 방식입니다. 입출력 작업을 수행하는 동안 스레드는 블로킹되지 않으며, 입출력 작업의 완료 여부를 확인하고, 필요에 따라 추가적인 작업을 수행할 수 있습니다. 이는 입출력 작업이 오래 걸리더라도 다른 작업들의 처리가 블로킹되지 않으므로, 더 효율적인 다중 작업 처리가 가능합니다.

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.*;

public class NonBlockingIOExample {
    public static void main(String[] args) {
        try {
            Path path = Paths.get("input.txt");
            FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ);
            ByteBuffer buffer = ByteBuffer.allocate(1024);

            int bytesRead = fileChannel.read(buffer); // 블로킹되지 않고 읽기를 시도함

            if (bytesRead != -1) {
                buffer.flip();
                byte[] data = new byte[buffer.remaining()];
                buffer.get(data);
                System.out.println("Read " + bytesRead + " bytes: " + new String(data));
            }

            fileChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

위 예시에서 'read()' 메서드가 블로킹되지 않고 일기를 시도하면, 데이터를 읽기 전까지 다른 작업을 수행할 수 있습니다. 

  1. 'fileChannel.read(buffer)'는 블로킹되지 않고 데이터 읽기를 시도
  2. 데이터가 바로 읽혀지지 않을 수도 있음
  3. 하지만 이 메서드는 블로킹되지 않으므로 즉시 다음 코드를 실행
  4. 데이터가 준비되면 'bytesRead'에 읽은 바이트 수가 저장
  5. 이후 'if (bytesRead != -1)' 조건문을 통해 데이터를 정상적으로 읽었을 때만 처리

따라서, 'fileChannerl.close()' 메서드는 'bytesRead' 변수와 상관없이 'read()' 메서드를 호출하더라도 먼저 실행될 수 있습니다.