자바 에서 BIO,NIO,AIO 는 어떤 차이 가 있 습 니까?

18204 단어 자바BIONIOAIO구별
1.BIO(Blocking IO,old IO 라 고도 함)
동기 화 블록 모델,클 라 이언 트 연결 에 대응 하 는 처리 스 레 드
모든 새로운 네트워크 연결 에 대해 하나의 라인 에 분배 되 고 라인 마다 자신 이 맡 은 입력 과 출력 을 독립 적 으로 처리 하 며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 의 차이 점 에 관 한 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기