본문 바로가기

프로그래밍/개발

IO와 NIO

WAS개발 중에 있었던 요구사항 중 하나이다. 

  • 만약 java.nio를 사용하고 있었다면 java.io를 사용하도록 수정한다.

이 요구사항을 봤을때 처음 드는 생각은 내가 io를 어디에서 쓰고 nio를 어디서 쓰지? 였고 그리고 굳이 왜? 라는 생각이 들었다. 그렇다면 io, nio가 무엇인지 먼저 살펴 보도록 하자.

 

io는 input/ output의 줄인말이고 chatgpt선생님의 말을 참고하자면 

I/O(Input/Output)와 NIO(New I/O)는 Java에서 데이터를 읽고 쓰는 방법을 개선하기 위해 도입된 두 가지 접근 방식입니다.

  1. I/O (기존의 전통적인 입출력 방식):
    • 입출력 작업은 스트림(Stream)을 통해 이루어집니다. 입력 스트림(Input Stream)은 데이터를 읽고, 출력 스트림(Output Stream)은 데이터를 씁니다.
    • 입출력 작업은 대부분 동기적(synchronous)으로 이루어집니다. 즉, 입출력 작업이 완료될 때까지 대기하며, 다른 작업을 수행하지 않습니다.
    • 스레드당 하나의 작업을 처리하므로, 많은 스레드가 동시에 작업을 수행할 경우 비효율적일 수 있습니다.
    • 대용량 데이터를 처리할 때 성능이 저하될 수 있습니다.
  2. NIO (New I/O 또는 Non-blocking I/O):
    • 입출력 작업은 채널(Channel)을 통해 이루어집니다. 입출력 작업은 버퍼(Buffer)를 통해 이루어지며, 입출력 스레드는 버퍼에 데이터를 읽고 쓸 수 있습니다.
    • 비동기적(asynchronous)으로 입출력 작업을 처리할 수 있습니다. 즉, 입출력 작업이 완료되지 않아도 대기하지 않고 다른 작업을 수행할 수 있습니다.
    • 채널을 통해 다수의 작업을 하나의 스레드로 처리할 수 있으므로, 멀티스레드 환경에서도 효율적으로 작업을 처리할 수 있습니다.
    • 대용량 데이터를 처리할 때 뛰어난 성능을 보입니다.

그래서 현재는 NIO방식을 많이 쓰지만 이를 섞어 썼을 때 문제점으로 서로 다른 입출력 모델(스트림, 버퍼) 을 사용하기 때문에 비효율적이게 될 수 도있고 오류를 발생할 수 도 있다. 나같은 경우에는 ios_base::sync_with_stdio(0); cin.tie(0); 을 사용했을때 scanf를 사용하면 안되는 이유가 stream의 동기화를 끊어 c의 함수를 쓸수 없기 때문인데, 이런것이라고 생각했다.

 

여기서 NIO옆에 Non-blocking I/O라는 용어가 중요한데, 블로킹, 논블로킹, 동기, 비동기에 대해서 공부해 보면 좋은 것 같다.

 

 

참고해보자

https://dev-coco.tistory.com/42

https://velog.io/@nittre/%EB%B8%94%EB%A1%9C%ED%82%B9-Vs.-%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9-%EB%8F%99%EA%B8%B0-Vs.-%EB%B9%84%EB%8F%99%EA%B8%B0