자바 에서 BIO,NIO,AIO 는 어떤 차이 가 있 습 니까?
동기 화 블록 모델,클 라 이언 트 연결 에 대응 하 는 처리 스 레 드
모든 새로운 네트워크 연결 에 대해 하나의 라인 에 분배 되 고 라인 마다 자신 이 맡 은 입력 과 출력 을 독립 적 으로 처리 하 며
Connection Per Thread
이 라 고도 부른다.단점:
1.IO 코드 에서 read 작업 은 차단 작업 입 니 다.연결 이 데이터 읽 기와 쓰기 작업 을 하지 않 으 면 스 레 드 가 막 히 고 자원 을 낭비 할 수 있 습 니 다.
2.스 레 드 가 많 으 면 서버 스 레 드 가 너무 많 고 스트레스 가 너무 많 습 니 다.예 를 들 어 C10K 문제 등 입 니 다.
c10k 문제 란 서버 가 수천 개의 클 라 이언 트 를 동시에 지원 하 는 문 제 를 말한다.즉,concurrent 1000 connection 이다.
응용 장면:BIO 방식 은 연결 수량 이 비교적 작고 고정된 구조 에 적용 되 는데 이런 방식 은 서버 자원 에 대한 요구 가 비교적 높 지만 프로그램 은 쉽게 이해 할 수 있다.
예제 코드 는 다음 과 같다.
바 이오 서버
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @Title:BIO
* @Author:wangchenggong
* @Date 2021/4/13 9:41
* @Description
* @Version
*/
public class SocketServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9000);
while (true){
System.out.println(" ...");
Socket clientSocket = serverSocket.accept();
System.out.println(" "+clientSocket.getRemoteSocketAddress()+" !");
handle(clientSocket);
}
}
private static void handle(Socket clientSocket) throws IOException{
byte[] bytes = new byte[1024];
int read = clientSocket.getInputStream().read(bytes);
System.out.println("read "+clientSocket.getRemoteSocketAddress()+" ");
if(read != -1){
System.out.println(" :" + new String(bytes, 0, read));
}
clientSocket.getOutputStream().write("HelloClient".getBytes());
clientSocket.getOutputStream().flush();
}
}
바 이오 클 라 이언 트
import java.io.IOException;
import java.net.Socket;
/**
* @Title:BIO
* @Author:wangchenggong
* @Date 2021/4/13 9:49
* @Description
* @Version
*/
public class SocketClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 9000);
//
socket.getOutputStream().write("HelloServer".getBytes());
socket.getOutputStream().flush();
System.out.println(" ");
byte[] bytes = new byte[1024];
//
socket.getInputStream().read(bytes);
System.out.println(" :" + new String(bytes));
socket.close();
}
}
2.NIO(Non Blocking IO,본의 아니 게 new IO)동기 화 비 차단,서버 구현 모드 는 하나의 스 레 드 로 여러 개의 연결 요청(연결)을 처리 할 수 있 습 니 다.클 라 이언 트 가 보 낸 연결 요청 은 다 중 복합 기 selector 에 등록 되 고 다 중 복합 기 는 연결 에 IO 요청 이 있 으 면 처리 하 며 JDK 1.4 에서 시작 되 었 습 니 다.
응용 장면:NIO 방식 은 연결 수량 이 많 고 연결 이 비교적 짧 은 구조 에 적합 하 다.예 를 들 어 채 팅 서버,탄막 시스템,서버 간 통신,프로 그래 밍 이 상대 적 으로 복잡 하 다.
NIO 는 채널(채널),버퍼(버퍼),Selector(다 중 복합 기)세 가지 핵심 구성 요소 가 있 습 니 다.
1.channel 은 흐름 과 유사 합 니 다.모든 channel 은 하나의 buffer 버퍼 에 대응 하고 buffer 바 텀 은 배열 입 니 다.
2.channel 은 selector 에 등록 되 어 있 으 며,selector 는 channel 읽 기와 쓰기 이벤트 의 발생 에 따라 빈 스 레 드 로 처리 합 니 다.
3.NIO 의 버 퍼 와 채널 은 모두 읽 을 수도 쓰 고 쓸 수도 있다.
NIO 의 코드 예 시 는 두 개 입 니 다.
멀 티 플 렉 서 를 도입 하지 않 은 NIO
서버
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @Title:Nio
* @Author:wangchenggong
* @Date 2021/4/14 11:04
* @Description
* @Version
*/
public class NioServer {
/**
*
*/
static List<SocketChannel> channelList = new ArrayList<>();
public static void main(String[] args) throws IOException {
// Nio ServerSocketChannel
ServerSocketChannel serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(9000));
// ServerSocketChannel
serverSocket.configureBlocking(false);
System.out.println("Nio ");
while(true){
// accept
/// NIO , linux accept
SocketChannel socketChannel = serverSocket.accept();
if(socketChannel != null){
System.out.println(" ");
socketChannel.configureBlocking(false);
channelList.add(socketChannel);
}
Iterator<SocketChannel> iterator = channelList.iterator();
while(iterator.hasNext()){
SocketChannel sc = iterator.next();
ByteBuffer byteBuffer = ByteBuffer.allocate(128);
// read
int len = sc.read(byteBuffer);
if(len > 0){
System.out.println(" :" + new String(byteBuffer.array()));
}else if(len == -1){
iterator.remove();
System.out.println(" ");
}
}
}
}
}
클 라 이언 트
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
/**
* @Title:Nio
* @Author:wangchenggong
* @Date 2021/4/14 11:36
* @Description
* @Version
*/
public class NioClient {
public static void main(String[] args) throws IOException {
SocketChannel socketChannel=SocketChannel.open(new InetSocketAddress("localhost", 9000));
socketChannel.configureBlocking(false);
ByteBuffer writeBuffer=ByteBuffer.wrap("HelloServer1".getBytes());
socketChannel.write(writeBuffer);
System.out.println(" 1 ");
writeBuffer = ByteBuffer.wrap("HelloServer2".getBytes());
socketChannel.write(writeBuffer);
System.out.println(" 2 ");
writeBuffer = ByteBuffer.wrap("HelloServer3".getBytes());
socketChannel.write(writeBuffer);
System.out.println(" 3 ");
}
}
다 중 복합 기 를 도입 한 NIO서버
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;
/**
* @Title: NIO
* @Author:wangchenggong
* @Date 2021/4/14 13:57
* @Description
* SelectionKey.OP_ACCEPT ―― , ,
* SelectionKey.OP_CONNECT ―― ,
* SelectionKey.OP_READ ―― , , ( , )
* SelectionKey.OP_WRITE ―― , ( )
*
* 1. SelectionKey.OP_READ , write , , isReadable()=true;
*
* 2. SelectionKey.OP_WRITE , isWritable() true,
* @Version
*/
public class NioSelectorServer {
public static void main(String[] args) throws IOException {
/**
* server , ,
*/
// ServerSocketChannel
ServerSocketChannel serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(9000));
// ServerSocketChannel
serverSocket.configureBlocking(false);
// selector channel, epoll
Selector selector = Selector.open();
// ServerSocketChannel selector , selector accept
serverSocket.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("NioSelectorServer ");
while(true){
//
selector.select();
// selector SelectionKey
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
// selectionKeys,
while (iterator.hasNext()){
SelectionKey key = iterator.next();
// OP_ACCEPT ,
if(key.isAcceptable()){
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
//
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
// SocketChannel selector , selector read ( )
socketChannel.register(selector, SelectionKey.OP_READ);
System.out.println(" "+socketChannel.getRemoteAddress()+" !");
}else if(key.isReadable()){
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(128);
int len = socketChannel.read(byteBuffer);
if(len > 0){
System.out.println(" "+socketChannel.getRemoteAddress()+" , :"+new String(byteBuffer.array()));
}else if(len == -1){
System.out.println(" ");
//
socketChannel.close();
}
}
// key, select
iterator.remove();
}
}
/**
* NioSelectorServer
* /127.0.0.1:57070 !
* /127.0.0.1:57070 , :HelloServer
* /127.0.0.1:57121 !
* /127.0.0.1:57121 , :HelloServer
*/
}
}
클 라 이언 트
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;
import java.util.Set;
/**
* @Title: NIO
* @Author:wangchenggong
* @Date 2021/4/14 14:39
* @Description
* @Version
*/
public class NioSelectorClient {
public static void main(String[] args) throws IOException {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
Selector selector = Selector.open();
// ,
socketChannel.register(selector, SelectionKey.OP_CONNECT);
socketChannel.connect(new InetSocketAddress("localhost", 9000));
while (true){
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iterator = keys.iterator();
while (iterator.hasNext()){
SelectionKey key = iterator.next();
iterator.remove();
if (key.isConnectable()){
SocketChannel sc = (SocketChannel) key.channel();
if (sc.finishConnect()){
System.out.println(" ");
ByteBuffer writeBuffer=ByteBuffer.wrap("HelloServer".getBytes());
sc.write(writeBuffer);
System.out.println(" ");
}
}
}
}
/**
*
*
*/
}
}
3.AIO(Asynchronous IO)즉 NIO 2.0비동기 비 차단 은 운영 체제 가 완 료 된 후에 서버 프로그램 이 스 레 드 를 시작 하여 처리 하 는 것 을 알 립 니 다.일반적으로 연결 수가 많 고 연결 시간 이 긴 응용 에 적 용 됩 니 다.
응용 장면:AIO 방식 은 연결 수량 이 많 고 연결 시간 이 비교적 긴 구조(응용)에 적용 되 며 JDK 7 이 지원 하기 시작 합 니 다.
유명한 비동기 네트워크 통신 프레임 워 크 netty 가 AIO 를 폐기 한 이 유 는 Linux 시스템 에서 NIO 의 바 텀 은 Epoll 을 사 용 했 고 AIO 의 바 텀 실현 은 Epoll 을 사용 하여 AIO 를 잘 실현 하지 못 했 기 때문에 성능 에 있어 현저 한 장점 이 없 으 며 JDK 에 의 해 깊이 최적화 되 기 쉽 지 않 고 Linux 에서 AIO 가 아직 성숙 하지 않 기 때문이다.
AIO 예제 코드 는 다음 과 같 습 니 다.
서버
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
/**
* @Title:Aio
* @Author:wangchenggong
* @Date 2021/4/14 17:05
* @Description
* @Version
*/
public class AioServer {
public static void main(String[] args) throws Exception {
final AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(9000));
serverChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
@Override
public void completed(AsynchronousSocketChannel socketChannel, Object attachment) {
try{
System.out.println("2--"+Thread.currentThread().getName());
//
serverChannel.accept(attachment,this);
System.out.println(" "+socketChannel.getRemoteAddress()+" ");
ByteBuffer buffer = ByteBuffer.allocate(128);
socketChannel.read(buffer, null, new CompletionHandler<Integer, Object>() {
@Override
public void completed(Integer result, Object attachment) {
System.out.println("3--"+Thread.currentThread().getName());
//flip Buffer
// , , byte=0 。 buffer.flip(); , buffer buffer
buffer.flip();
System.out.println(new String(buffer.array(), 0, result));
socketChannel.write(ByteBuffer.wrap("hello Aio Client!".getBytes()));
}
@Override
public void failed(Throwable exc, Object attachment) {
exc.printStackTrace();
}
});
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, Object attachment) {
}
});
System.out.println("1\\main"+Thread.currentThread().getName());
Thread.sleep(Integer.MAX_VALUE);
}
/**
* 1\\mainmain
* 2--Thread-9
* /127.0.0.1:54821
* 3--Thread-8
* hello AIO server !
* 2--Thread-9
* /127.0.0.1:54942
* 3--Thread-7
* hello AIO server !
*/
}
클 라 이언 트
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
/**
* @Title:Aio
* @Author:wangchenggong
* @Date 2021/4/14 16:56
* @Description
* @Version
*/
public class AioClient {
public static void main(String[] args) throws Exception {
// Aio
AsynchronousSocketChannel socketChannel = AsynchronousSocketChannel.open();
socketChannel.connect(new InetSocketAddress("localhost", 9000)).get();
//
socketChannel.write(ByteBuffer.wrap("hello AIO server !".getBytes()));
//
ByteBuffer buffer = ByteBuffer.allocate(128);
Integer len = socketChannel.read(buffer).get();
if(len != -1){
// :hello Aio Client!
System.out.println(" :"+new String(buffer.array(), 0, len));
}
}
}
총화BIO
NIO
AIO
IO 모델
동기 블록
동기 비 차단
비동기 비 차단
프로 그래 밍 난이도
간단 하 다.
복잡 하 다.
복잡 하 다.
신 빙 성 이 좋다
활용 단어 참조
좋다
좋다
물동량
낮다
높다
높다
자바 에서 BIO,NIO,AIO 가 어떤 차이 가 있 는 지 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.자바 에서 BIO,NIO,AIO 의 차이 점 에 관 한 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.