Akashic Records

자바 nio - 12 본문

오래된글/Java

자바 nio - 12

Andrew's Akashic Records 2018. 4. 9. 12:47
728x90

12. SelectableChannel 클래스

자, 이제 1.4버전에서 새롭게 추가된 네트워크를 입출력 부분을 보자. 우선 크게 본다면 다음 3가지의 클래스를 반드시 이해를 해야한다.

  1. SelectableChannel 클래스 : 채널로서 관리대상(예들들어 서버소켓, 소켓....)

  2. Selector 클래스 : 채널 관리자.

  3. SelectionKey 클래스 : 채널들을 다룰때 필요한 정보.

위 클래스는 서로 연관성을 가지고 있는데 이들의 중요성은 non-blocking I/O의 지원을 해준다는 것이다. 물론 그외 장점들을 가지고 있다. 이들 관계를 간단히 말한다면 Selector클래스는 SelectableChannel 클래스를 SelectionKey로 관리한다. 즉 Selector는 관리자 역활을 하며 SelectableChannel는 서버와 클라이언트 사이에 일어난 작업을 하는 것이고 SelectionKey는 Selector가 SelectableChannel를 구별하는 정보가 된다. 이제 이를 하나씩 살펴보자.


1. SelectableChannel 클래스 정의

Selector에 의한 관리나 Non-Blocking I/O를 위한 기본적인 기능을 가진 Abstract class이다. SelectableChannel은 Selector클래스에 의해 선택될 수 있으며 Non-Blocking I/O를 가능하게 해준다. 가능한 이유는 AbstractInterruptibleChannel 클래스를 상속하기 때문이다.

non-blocking I/O vs blocking I/O

  1. blocking I/O이란 무엇인가?

  2. 우선 blocking I/O는 우리가 앞서 소켓프로그램을 배울때 잘 알고 있을것이다. 예를 들면 서버소켓이 클라이언트의 접속을 기다릴때나 입력이나 출력이 일어나는 경우, 이들은 블록화가 된다. 즉 모든 입출력에 대해 그 동작이 완료될때까지 서버는 기다린다는 뜻이다. 이는 접속하는 클라이언트 수많큼 스레드를 생성해야 하는 결과를 낳았으며 접속만 하고 아무것도 하지 않는 클라이언트인 경우 스레드도 역시 가만히 있어야 한다는 것이다. 이는 스레드 낭비이자 서버의 낭비이다. 참고로 한 스레드 하나당 1MB의 메모리가 할당된다.

  3. non-blocking I/O이란 무엇인가?

  4. non-blocking은 접속한 클라이언트 수 만큼 스레드를 만들어서 처리를 하는 것이 아니라 하나의 스레드만으로 Selector만을 계속 지켜보고 있으면 Selector가 실제 입출력이 일어난 채널이 있으면 이를 알려주어 그때그때 이를 처리할 수 있다는 것이다. 이렇게 하면 모든 채널에 대해서 각각의 스레드가 존재할 필요가 없다.


2. SelectableChannel 클래스 주요 메서드

- public final SelectionKey register (Selector sel, int ops) : 현재 채널을 sel로 지정된 selector에 등록하되 어떤 입출력 동작(ops)에 대해 선택할 것인지를 지정한다. 리턴값으로 SelectionKey 클래스의 인스턴스를 리턴한다. 여기서 ops는 입출력 동작의 종류를 나타내는 것으로 SelectionKey클래스에 정의되어 있다. 이 ops는 4가지로 다음과 같다.

  • public static final int OP_ACCEPT

  • public static final int OP_CONNECT

  • public static final int OP_READ

  • public static final int OP_WRITE

-public abstract SelectionKey register (Selector sel, int ops, Object att) : 위와 같은 역활을 하는 메서드로 인자로 att가 추가되었다. att는 해당 채널에 부가적으로 필요한 객체를 지정하는 것으로 Selector를 통해 SelectionKey만 얻을 수 있기 때문에 부가적인 정보를 담는 이러한 객체는 유용하게 사용된다.

==> register()메서드는 채널을 Selector에 등록시키는 메서드인데 이러한 등록은 한번에 하나의 Selector에만 가능하면 하나의 SelectableChannel 은 여러개의 Selector에 등록하는 것은 불가능하다.

==> 등록취소가 되는 경우

SelectionKey클래스의 cancel()메소드에 의해/SelectableChannel이 close()가 되는 경우/스레드가 intrrupt()가 되는 경우

- public abstract boolean isRegistered () : 현재 이 채널이 selector에 등록되어 있는지 아닌지를 판단.

- public abstract SelectableChannel configureBlocking (boolean block) : 채널의 입출력 모드를 선택한다. 인자인 block이 true 이면 blocking I/O , false 이면 Non-Blocking I/O이다. 이는 Selector에 등록한 후에는 바꿀 수 없다.

- public abstract boolean isBlocking () : 현재 채널의 입출력 모드를 알아 낸다.

- public abstract SelectionKey keyFor (Selector sel) : 인자로 들어온 sel에 해당 채널이 등록이 되어 있다면 해당 SelectionKey를 얻을 수 있다. 등록되어 있지 않는 경우는 null을 리턴한다.

- public abstract int validOps () : 현재 채널이 할 수 있는 입출력 동작을 리턴해준다. 리턴값으로 앞서 살펴본 SelectionKey클래스의 클래스 상수인 4가지이다.



728x90

'오래된글 > Java' 카테고리의 다른 글

자바 nio - 14  (0) 2018.04.09
자바 nio - 13  (0) 2018.04.09
자바 nio - 11  (0) 2018.04.09
자바 nio - 10  (0) 2018.04.09
자바 nio - 9  (0) 2018.04.09
Comments