자바 NIO 원리 그림 분석 및 코드 구현
최근 hadop 의 RPC (Remote Procedure Call Protocol, 원 격 프로 세 스 호출 프로 토 콜) 를 분석 하고 있 습 니 다. 네트워크 를 통 해 원 격 컴퓨터 프로그램 에서 서 비 스 를 요청 하고 바 텀 네트워크 기술 을 알 필요 가 없 는 프로 토 콜 입 니 다. 참고 할 수 있 습 니 다. http://baike.baidu.com/view/32726.htm )메커니즘 을 발견 할 때 hadop 의 RPC 메커니즘 의 실현 은 주로 두 가지 기술 을 사용 했다. 동적 에이전트 (동적 에이 전 트 는 블 로 그 를 참고 할 수 있다. http://weixiaolu.iteye.com/blog/1477774 )자바 NIO 와. hadop 의 RPC 소스 코드 를 정확하게 분석 하기 위해 서 는 자바 NIO 의 원리 와 구체 적 인 실현 을 먼저 연구 할 필요 가 있다 고 생각 합 니 다. 이 블 로 그 는 주로 두 가지 방향 으로 자바 NIO 디 렉 터 리 를 분석 합 니 다. 1. 자바 NIO 와 I / O 의 차 이 를 차단 합 니 다. 1. 차단 I / O 통신 모델 2. 자바 NIO 원리 및 통신 모델 2. 자바 NIO 서버 와 클 라 이언 트 코드 구현 구체 적 인 분석: 1. 자바 NIO 와 차단 I / O 의 차이 1. 차단 I / O 통신 모델 만약 지금 차단 I / O 에 대해 어느 정도 알 고 있다 면, 차단 I / O 는 InputStream. read () 방법 을 호출 할 때 차단 되 어 있다 는 것 을 알 고 있 습 니 다. 데이터 가 올 때 (또는 시간 초과) 까지 기 다 려 야 돌아 올 것 입 니 다. 마찬가지 로, ServerSocket. accept () 를 호출 하고 있 습 니 다.방법 은 클 라 이언 트 연결 이 있어 야 돌아 올 때 까지 차단 합 니 다. 모든 클 라 이언 트 가 연결 되면 서버 에서 클 라 이언 트 의 요청 을 처리 하기 위해 스 레 드 를 시작 합 니 다. I / O 를 막 는 통신 모델 설명도 는 다음 과 같 습 니 다.
자세히 분석 해 보면 차단 I / O 에 단점 이 있 을 것 입 니 다. 차단 I / O 통신 모델 에 따라 두 가지 단점 을 정리 하 였 습 니 다. 1. 클 라 이언 트 가 많 을 때 대량의 처리 스 레 드 를 만 들 것 입 니 다. 또한 모든 스 레 드 는 스 택 공간 과 CPU 시간 을 차지 해 야 합 니 다. 2. 차단 은 빈번 한 컨 텍스트 전환 을 가 져 올 수 있 고 대부분의 컨 텍스트 전환 은 무의미 할 수 있 습 니 다. 여기 서어떤 상황 에서 비 차단 식 I / O 는 응용 전망 이 있다. 자바 NIO 원리 및 통신 모델 자바 NIO 는 jdk 1.4 에서 사용 되 기 시 작 했 습 니 다. '새로운 I / O' 라 고도 할 수 있 고 비 차단 식 I / O 라 고도 할 수 있 습 니 다. 다음은 자바 NIO 의 작업 원리 입 니 다. 1. 하나의 전문 적 인 스 레 드 로 모든 IO 사건 을 처리 하고 배 포 를 책임 집 니 다. 2. 사건 구동 메커니즘: 사건 이 도 착 했 을 때 발생 하 는 것 이지 동시에 사건 을 감시 하 는 것 이 아니다. 3. 스 레 드 통신: 스 레 드 간 에 wait, notify 등 방식 으로 통신 합 니 다. 매번 컨 텍스트 전환 이 의미 가 있 습 니 다. 불필요 한 스 레 드 전환 을 줄 입 니 다. 몇 가지 자 료 를 읽 은 후에 제 가 이해 하 는 자바 NIO 의 작업 원리 도 를 붙 입 니 다.
(비고: 모든 스 레 드 의 처리 절 차 는 데이터 읽 기, 디 코딩, 계산 처리, 인 코딩, 응답 보 내기 입 니 다.) 자바 NIO 서버 는 하나의 전문 스 레 드 만 시작 하여 모든 IO 사건 을 처리 합 니 다. 이런 통신 모델 은 어떻게 실현 되 었 습 니까? 하하, 우리 함께 그것 의 비밀 을 탐구 합 시다. 자바 NIO 는 양 방향 채널 (channel) 을 사용 합 니 다.단 방향 스 트림 (stream) 이 아 닌 데이터 전송 을 진행 합 니 다. 채널 에 관심 있 는 이 벤트 를 등록 할 수 있 습 니 다. 모두 다음 과 같은 네 가지 이벤트 가 있 습 니 다.
이벤트 이름
대응 값
서버 수신 클 라 이언 트 연결 이벤트
SelectionKey.OP_ACCEPT(16)
클 라 이언 트 연결 서버 이벤트
SelectionKey.OP_CONNECT(8)
읽 기 이벤트
SelectionKey.OP_READ(1)
이벤트 쓰기
SelectionKey.OP_WRITE(4)
서버 와 클 라 이언 트 는 각각 관리 채널 의 대상 을 유지 합 니 다. 우 리 는 selector 라 고 부 릅 니 다. 이 대상 은 하나 이상 의 채널 (channel) 의 이 벤트 를 감지 할 수 있 습 니 다. 서버 의 예 를 들 어 서버 의 selector 에 읽 기 이 벤트 를 등록 하면 클 라 이언 트 가 서버 에 데 이 터 를 보 내 고 I / O 를 막 을 때 read () 를 호출 합 니 다.방법 은 데 이 터 를 차단 적 으로 읽 고 NIO 서버 는 selector 에 읽 기 이 벤트 를 추가 합 니 다. 서버 의 처리 스 레 드 는 selector 에 문의 적 으로 접근 합 니 다. selector 에 방문 할 때 관심 있 는 이벤트 가 도착 하면 이 사건 들 을 처리 합 니 다. 관심 있 는 이벤트 가 도착 하지 않 으 면 관심 있 는 이벤트 가 도착 할 때 까지 스 레 드 를 처리 합 니 다. 다음은 제 이치 입 니 다.자바 NIO 의 통신 모델 설명도:
2. 자바 NIO 서버 와 클 라 이언 트 코드 구현 자바 NIO 를 잘 이해 하기 위해 서버 와 클 라 이언 트 의 간단 한 코드 를 붙 여 구현 합 니 다. 서버:
package cn.nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
/**
* NIO
* @author
*/
public class NIOServer {
//
private Selector selector;
/**
* ServerSocket ,
* @param port
* @throws IOException
*/
public void initServer(int port) throws IOException {
// ServerSocket
ServerSocketChannel serverChannel = ServerSocketChannel.open();
//
serverChannel.configureBlocking(false);
// ServerSocket port
serverChannel.socket().bind(new InetSocketAddress(port));
//
this.selector = Selector.open();
// , SelectionKey.OP_ACCEPT , ,
// ,selector.select() , selector.select() 。
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
}
/**
* selector , ,
* @throws IOException
*/
@SuppressWarnings("unchecked")
public void listen() throws IOException {
System.out.println(" !");
// selector
while (true) {
// , ; ,
selector.select();
// selector ,
Iterator ite = this.selector.selectedKeys().iterator();
while (ite.hasNext()) {
SelectionKey key = (SelectionKey) ite.next();
// key,
ite.remove();
//
if (key.isAcceptable()) {
ServerSocketChannel server = (ServerSocketChannel) key
.channel();
//
SocketChannel channel = server.accept();
//
channel.configureBlocking(false);
//
channel.write(ByteBuffer.wrap(new String(" ").getBytes()));
// , , 。
channel.register(this.selector, SelectionKey.OP_READ);
//
} else if (key.isReadable()) {
read(key);
}
}
}
}
/**
*
* @param key
* @throws IOException
*/
public void read(SelectionKey key) throws IOException{
// : Socket
SocketChannel channel = (SocketChannel) key.channel();
//
ByteBuffer buffer = ByteBuffer.allocate(10);
channel.read(buffer);
byte[] data = buffer.array();
String msg = new String(data).trim();
System.out.println(" :"+msg);
ByteBuffer outBuffer = ByteBuffer.wrap(msg.getBytes());
channel.write(outBuffer);//
}
/**
*
* @throws IOException
*/
public static void main(String[] args) throws IOException {
NIOServer server = new NIOServer();
server.initServer(8000);
server.listen();
}
}
클 라 이언 트:
package cn.nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
/**
* NIO
* @author
*/
public class NIOClient {
//
private Selector selector;
/**
* Socket ,
* @param ip ip
* @param port
* @throws IOException
*/
public void initClient(String ip,int port) throws IOException {
// Socket
SocketChannel channel = SocketChannel.open();
//
channel.configureBlocking(false);
//
this.selector = Selector.open();
// , , listen()
// channel.finishConnect();
channel.connect(new InetSocketAddress(ip,port));
// , SelectionKey.OP_CONNECT 。
channel.register(selector, SelectionKey.OP_CONNECT);
}
/**
* selector , ,
* @throws IOException
*/
@SuppressWarnings("unchecked")
public void listen() throws IOException {
// selector
while (true) {
selector.select();
// selector
Iterator ite = this.selector.selectedKeys().iterator();
while (ite.hasNext()) {
SelectionKey key = (SelectionKey) ite.next();
// key,
ite.remove();
//
if (key.isConnectable()) {
SocketChannel channel = (SocketChannel) key
.channel();
// ,
if(channel.isConnectionPending()){
channel.finishConnect();
}
//
channel.configureBlocking(false);
//
channel.write(ByteBuffer.wrap(new String(" ").getBytes()));
// , , 。
channel.register(this.selector, SelectionKey.OP_READ);
//
} else if (key.isReadable()) {
read(key);
}
}
}
}
/**
*
* @param key
* @throws IOException
*/
public void read(SelectionKey key) throws IOException{
// read
}
/**
*
* @throws IOException
*/
public static void main(String[] args) throws IOException {
NIOClient client = new NIOClient();
client.initClient("localhost",8000);
client.listen();
}
}
소결: 드디어 동적 에이전트 와 자바 NIO 를 분 석 했 습 니 다. 하하, 다음은 hadop 의 RPC 체제 소스 코드 를 분석 하 겠 습 니 다. 블 로그 주소: http://weixiaolu.iteye.com/blog/1504898 。그러나 자바 NIO 의 이해 에 이의 가 있다 면 함께 토론 하 시 는 것 을 환영 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.