블로킹(Blocking)
블로킹이란, 어떤 작업이 수행될 때 해당 작업이 완료될 때까지 프로그램이 다른 일을 할 수 없는 상태를 말합니다.
즉, 입출력 작업을 수행할 때 결과가 반환될 때까지 대기하는 것입니다.
이러한 블로킹 모델은 I/O 작업이 끝날 때까지 스레드를 중단시켜 대기하도록 만들어져 있으며,
이는 시스템 자원의 비효율성을 야기할 수 있습니다.
아래는 블로킹 모델로 I/O 작업을 수행하는 Java 코드입니다.
import java.io.*;
public class BlockingIOExample {
public static void main(String[] args) {
try {
FileInputStream fileInputStream = new FileInputStream("input.txt");
byte[] buffer = new byte[1024];
int bytesRead = fileInputStream.read(buffer); // 블로킹 메소드
while (bytesRead != -1) {
System.out.println(new String(buffer, 0, bytesRead));
bytesRead = fileInputStream.read(buffer); // 블로킹 메소드
}
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
위 코드에서는 FileInputStream
을 사용하여 파일에서 데이터를 읽어오고, read()
메서드를 호출하여 데이터를 읽어옵니다. 이때 read()
메서드는 블로킹 메서드이므로, 데이터가 읽혀질 때까지 스레드가 대기하게 됩니다.
위 코드에서 FileInputStream.read()
메소드를 호출할 때, 만약 파일의 끝에 도달하면 -1을 반환하며 반복문에서 빠져나가게 됩니다. FileInputStream
은 파일에서 데이터를 읽어올 때 블로킹 모델을 사용하므로, 데이터가 읽혀질 때까지 스레드가 대기하게 됩니다. 이러한 블로킹 모델은 입출력 작업이 긴 시간이 걸리는 경우에는 문제가 될 수 있습니다.
논블로킹(Non-Blocking)
논블로킹 모델은 입출력 작업을 수행할 때 결과가 반환될 때까지 대기하지 않고, 다른 작업을 수행할 수 있도록 만든 모델입니다.
논블로킹 모델은 입출력 작업이 끝나지 않아도 다른 작업을 처리할 수 있으므로,
블로킹 모델에 비해 시스템 자원을 더 효율적으로 사용할 수 있습니다.
아래는 논블로킹 모델로 I/O 작업을 수행하는 Java 코드입니다.
java
Copy code
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class NonBlockingIOExample {
public static void main(String[] args) {
try {
FileInputStream fileInputStream = new FileInputStream("input.txt");
FileChannel fileChannel = fileInputStream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (fileChannel.read(buffer) > 0) {
buffer.flip();
System.out.println(new String(buffer.array()));
buffer.clear();
}
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
위 코드에서는 FileInputStream
을 사용하여 파일에서 데이터를 읽어오고, FileChannel
을 사용하여 파일에서 데이터를 읽어오는 논블로킹 방식으로 작성되었습니다. read()
메서드 대신에 FileChannel.read()
메서드를 사용하였으며, 이 메서드는 논블로킹 메서드이므로 결과가 즉시 반환됩니다.
또한, 데이터를 읽어온 후 ByteBuffer
를 사용하여 버퍼에 저장한 후, 버퍼에서 데이터를 읽어와 출력합니다. flip()
메서드를 호출하여 버퍼의 포지션(position)을 0으로 설정하고, clear()
메서드를 호출하여 버퍼를 초기화합니다.
위 코드에서 FileChannel.read()
메소드는 데이터가 읽혀지면 읽은 바이트 수를 반환하며, 파일의 끝에 도달하면 0을 반환합니다. 따라서 while문은 읽은 바이트 수가 0보다 클 때까지 반복됩니다.
이러한 논블로킹 모델은 입출력 작업이 긴 시간이 걸리는 경우에도 다른 작업을 수행할 수 있으므로 시스템 자원의 효율성을 높일 수 있습니다.
블로킹 vs. 논블로킹 비교
블로킹 모델은 입출력 작업이 끝날 때까지 대기하며, 논블로킹 모델은 입출력 작업을 수행하는 동안 다른 작업을 수행할 수 있습니다. 따라서, 논블로킹 모델은 블로킹 모델보다 성능이 향상될 수 있습니다.
하지만, 논블로킹 모델은 구현하기 어렵고 복잡하기 때문에, 코드의 복잡도가 높아질 수 있습니다.
즉, 입출력 작업이 빈번하게 발생하고, 대기 시간이 짧은 경우에는 블로킹 모델이 효율적입니다. 반면, 입출력 작업이 적고, 대기 시간이 긴 경우에는 논블로킹 모델이 효율적입니다.
따라서, 개발자는 입출력 작업의 특성에 맞게 블로킹 모델과 논블로킹 모델을 선택하고, 적절한 방식으로 구현해야 합니다.
'java' 카테고리의 다른 글
함수형 인터페이스 (0) | 2023.04.06 |
---|---|
Java Stream (0) | 2023.03.28 |
어노테이션(Annotation) 이란? (1) | 2022.07.11 |
J2EE란? (2) | 2022.05.30 |
JVM 메모리 구조 (1) | 2022.05.25 |