Non-blocking I/O(NIO)

2020. 11. 20. 13:30모바일/Android_Java

NIO

구분 IO NIO
버퍼 넌버퍼 버퍼
비동기 지원X 지원
블로킹/넌블로킹 블로킹만 지원 모두지원

스트림과 채널

스트림

  • 스트림 기반
  • 입력, 출력 스트림으로 구분되어 있다.(둘다생성해야함)
  • 버퍼 제공해주는 보조 스트림을 사용해야함
  • 이전 게시글 참조..
  • read()메소드로 블로킹된다.
  • write() 메소드로 데이터 출력 전까지 블로킹된다.

채널

  • 양방향으로 입,출력이 가능하다.
  • 하나의 파일에서 읽고 저장하는 작업을 모두 해야한다면 FileChannel만 생성하면 된다.
  • 스레드 인터럽트로 빠져나올 수 있다.
  • 넌블로킹 : 입출력 작업 준비가 완료된 채널만 선택해서 작업 스레드가 처리한다.
  • 셀렉터(Selector)가 여러개의 채널 중에서 준비 완료된 채널을 선택하는 방법을 제공함!

선택 기준?

  • NIO는 연결 클라이언트 수가 많고, 하나의 입출력 처리작업이 오래 걸리지 않은경우 좋다
  • 스레드 입출력 처리가 오래걸리면, 대기 작업 수가 늘어나 제한된 스레드로 처리하는것이 안좋을 수 있음
  • IO : 연결 클라이언트 수가 적고, 전송되는 데이터가 대용량이면서 순차적으로 처리될 필요성이 있을 경우에는 IO로 서버 구현하는것이 좋다.

버퍼

  • 읽고 쓰기가 가능한 메모리베열
구분 넌다이렉트 다이렉트
사용 메모리 JVM의 힙 운영체제 메모리
버퍼 생성 시간 빠름 느림
버퍼 크기 작다 크다(큰 데이터 처리)
입출력 성능 낮다 높다.(입출력 빈번할 때 유리)

다이렉트버퍼

  • 한 번 생성해 놓고 재사용하는 것이 적합하다.

사용

ByteBuffer directBuffer = ByterBuffer.aloocateDirect();

ByteBuffer nonDirectBuffer = ByteBuffer.allocate(용량);
  • 다이렉트 버퍼는 채널을 사용해서 버퍼의 데이터를 읽고, 쓸 경우에만 운영체제의 native I/O를 수행한다.
  • ByteBuffer의 get()/put()메소드를 사용해서 버퍼의 데이터를 읽고, 저장한다면 이 작업은 내부적으로 JNI를 호출해서 native I/O를 수행하기 때문에 JNI호 호출이라는 오버 헤더가 추가된다.
  • JNI : 자바 코드에서 C함수를 호출할 수 있도록 해주는 API이다.