傳統BIO的缺點/NIO的設計理念 使用NIO實現併發Demo

傳統BIO的缺點:

  1. 在accept的時候會作出放棄CPU的操作 線程阻塞
  2. 在socket.getInputStream.read();的時候會造成線程阻塞
  3. BIO想實現併發需要採用多線程的方式 但是多線程有很多缺點(最大的缺點:消耗程序資源)

傳統BIO服務器NetServer.class代碼

public class NetServer {

    static byte []bytes=new byte[1024];
    public static void main(String[] args) {

        try {
            ServerSocket serverSocket=new ServerSocket(9098);
            while (true) {
                System.out.println("accept wait coon");
                Socket socket = serverSocket.accept();
                System.out.println("conn success");
                System.out.println("read wait conn");
                //放棄CPU
                int read = socket.getInputStream().read(bytes);
                System.out.println(read+"========這是read的長度");
                System.out.println("data success");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

傳統BIO客戶端NetClient.class代碼

public class NetClient {
    public static void main(String[] args) {
        try {
            Socket socket=new Socket("127.0.0.1",9098);
            Scanner scanner=new Scanner(System.in);
            String next = scanner.next();
            socket.getOutputStream().write(next.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

NIO的設計理念: 使用單線程實現高併發
針對傳統BIO的缺點,sun公司推出了NIO

Nio Demo

package crawler.Socket;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName NioTemp
 * @Description TODO
 * @Author XuWenXiao
 * @Date 2020/5/15 9:47
 * @Version 1.0
 **/
public class NioTemp {
    static ByteBuffer byteBuffer=ByteBuffer.allocate(512);
    static List<SocketChannel> socketChannels=new ArrayList<SocketChannel>();
    public static void main(String[] args) {
        try {
            ServerSocketChannel serverSocket=ServerSocketChannel.open();
            SocketAddress socketAddress=new InetSocketAddress("127.0.0.1",9098);
            serverSocket.bind(socketAddress);
            //設置accept爲非阻塞
            serverSocket.configureBlocking(false);
            while (true){
                for (SocketChannel socketChannel : socketChannels) {
                    int read=socketChannel.read(byteBuffer);
                    if (read>0){
                        System.out.println(read+"讀取到數據的長度 read ");
                        byteBuffer.flip();
                        byte[]bytes=new byte[read];
                        byteBuffer.get(bytes);
                        String s=new String(bytes);
                        System.out.println(s);
                        byteBuffer.flip();
                    }
                }
                SocketChannel accept=serverSocket.accept();
                if (accept!=null){
                    System.out.println("conn success");
                    //設置read 操作爲非阻塞
                    accept.configureBlocking(false);
                    socketChannels.add(accept);
                    System.out.println(socketChannels.size()+"打印集合的長度 socketChannels.size()");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章