欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java中BIO、NIO、AIO的原理及其区别

程序员文章站 2022-07-10 16:23:24
...
IO的处理方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。
java中IO的主要来源是本地和网络传输。
在了解三种处理方式之前,先了解,同步异步,阻塞非阻塞:
  1、同步: 用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪; 例如自己亲自去       餐厅吃饭
  2、异步:  用户触发IO操作以后,可以干别的事,IO操作完成以后再通知当前线程;例如自己通过美团外卖订购了,送餐上面;自己在等餐到来时间可以干别的事情;
  3、阻塞: 当试图进读写文件的时候,发现不可读取或没东西读,则进入等待状态知道可读;例如去楼下排队等餐;
  4、非阻塞:用户进程访问数据时,会马上返回一个状态值(可读不可读);例如在餐厅吃饭,先取个号,然后坐着等待服务员报号才能入座吃饭(你可以不停的询问服务员还有多久)。(使用非阻塞IO时,如果不能读写Java调用会马上返回,当IO事件分发器会通知可读写时再继续进行读写,不断循环直到读写完成)。
一、同步阻塞BIO
    在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒绝请求,如果有的话,客户端会线程会等待请求结束后才继续执行。
Java中BIO、NIO、AIO的原理及其区别
            
    
    博客分类: java java、IO、NIO、AIO
该模型最大的问题就是缺乏弹性伸缩能力,当客户端并发访问量增加后,服务端的线程个数和客户端并发访问数呈1:1的正比关系,Java中的线程也是比较宝贵的系统资源,线程数量快速膨胀后,系统的性能将急剧下降,随着访问量的继续增大,系统最终就死掉了。不适合高并发和高性能方面。

二、同步非阻塞的NIO
  NIO详细文档:http://ifeve.com/java-nio-all/
  JDK 1.4中的java.nio.*包中引入新的Java I/O库,其目的是提高速度。实际上,“旧”的I/O包已经使用NIO重新实现过,即使我们不显式的使用NIO编程,也能从中受益。
  NIO我们一般认为是New I/O(也是官方的叫法),因为它是相对于老的I/O类库新增的(其实在JDK 1.4中就已经被引入了,但这个名词还会继续用很久,即使它们在现在看来已经是“旧”的了,所以也提示我们在命名时,需要好好考虑),做了很大的改变。但民间跟多人称之为Non-block I/O,即非阻塞I/O,因为这样叫,更能体现它的特点。而下文中的NIO,不是指整个新的I/O库,而是非阻塞I/O。
    NIO提供了与传统BIO模型中的Socket和ServerSocket相对应的SocketChannel和ServerSocketChannel两种不同的套接字通道实现。
    新增的着两种通道都支持阻塞和非阻塞两种模式。
    阻塞模式使用就像传统中的支持一样,比较简单,但是性能和可靠性都不好;非阻塞模式正好与之相反。
    对于低负载、低并发的应用程序,可以使用同步阻塞I/O来提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用,应使用NIO的非阻塞模式来开发。
服务端流程图:
Java中BIO、NIO、AIO的原理及其区别
            
    
    博客分类: java java、IO、NIO、AIO
客户端流程图:

Java中BIO、NIO、AIO的原理及其区别
            
    
    博客分类: java java、IO、NIO、AIO

客户端代码:
package com.example.demo.aio;

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;

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2018/3/12
 * Time: 18:15
 * To change this template use File | Settings | File Templates.
 */
public class NioClient implements Runnable{

    private String ip;
    private int port;
    private Selector selector;
    private SocketChannel socketChannel;
    private volatile boolean started;
    public NioClient(String ip,int port){
        this.ip=ip;
        this.port=port;
        try {
            //创建选择器
            selector =Selector.open();
            //打开监听端口
            socketChannel = SocketChannel.open(new InetSocketAddress(ip,port));
            socketChannel.configureBlocking(false);//设置非阻塞模式
            started = true;
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
    public void stop(){
        this.started = false;
    }
    @Override
    public void run() {
        //连接服务器
        try {
            doConnect();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
        //循环遍历selector  
        while (started) {
            try {
                //无论是否有读写事件发生,selector每隔1s被唤醒一次  
                selector.select(1000);
                //阻塞,只有当至少一个注册的事件发生的时候才会继续.  
//              selector.select();  
                Set<SelectionKey> keys = selector.selectedKeys();
                Iterator<SelectionKey> it = keys.iterator();
                SelectionKey key = null;
                while (it.hasNext()) {
                    key = it.next();
                    it.remove();
                    try {
                        handleInput(key);
                    } catch (Exception e) {
                        if (key != null) {
                            key.cancel();
                            if (key.channel() != null) {
                                key.channel().close();
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
        }
        //selector关闭后会自动释放里面管理的资源  
        if (selector != null)
            try {
                selector.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
         }

    private void handleInput(SelectionKey key) throws IOException {
        if(key.isValid()){
            SocketChannel sc = (SocketChannel) key.channel();
            if(key.isConnectable()){
                if(sc.finishConnect());
                else System.exit(1);
            }
            //读消息
            if(key.isReadable()){
                //创建ByteBuffer,并开辟一个1M的缓冲区
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                //读取请求码流,返回读取到的字节数
                int readBytes = sc.read(buffer);
                //读取到字节,对字节进行编解码
                if(readBytes>0){
                    //将缓冲区当前的limit设置为position=0,用于后续对缓冲区的读取操作
                    buffer.flip();
                    //根据缓冲区可读字节数创建字节数组
                    byte[] bytes = new byte[buffer.remaining()];
                    //将缓冲区可读字节数组复制到新建的数组中
                    buffer.get(bytes);
                    String result = new String(bytes,"UTF-8");
                    System.out.println("客户端收到消息:" + result);
                }
                //没有读取到字节 忽略
//              else if(readBytes==0);
                //链路已经关闭,释放资源
                else if(readBytes<0){
                    key.cancel();
                    sc.close();
                }
            }
        }
    }

    private void doConnect() throws IOException {
        if(socketChannel.connect(new InetSocketAddress(this.ip,this.port)));
        else socketChannel.register(selector, SelectionKey.OP_CONNECT);
    }
    public void sendMsg(String message) throws IOException {
        socketChannel.register(selector,SelectionKey.OP_READ);
        doWrite(socketChannel,message);
    }
    //异步发送消息
    private void doWrite(SocketChannel channel,String request) throws IOException{
        //将消息编码为字节数组
        byte[] bytes = request.getBytes();
        //根据数组容量创建ByteBuffer
        ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
        //将字节数组复制到缓冲区
        writeBuffer.put(bytes);
        //flip操作
        writeBuffer.flip();
        //发送缓冲区的字节数组
        channel.write(writeBuffer);
        //****此处不含处理“写半包”的代码
    }
}


package com.example.demo.aio;

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2018/3/13
 * Time: 9:13
 * To change this template use File | Settings | File Templates.
 */
public class RunClient {
    private final static int DEFUALT_PORT=12345;
    private final static String SERVER_IP="127.0.0.1";
    private static NioClient nioClient;

    public static void start(){
        start(DEFUALT_PORT,SERVER_IP);
    }
    public synchronized static void start(int port,String ip){
        if(nioClient!=null)
            nioClient.stop();
        nioClient = new NioClient(ip,port);
        new Thread(nioClient,"client").start();
    }
    //向服务器发送消息
    public static boolean sendMsg(String msg) throws Exception{
        if(msg.equals("q")) return false;
        nioClient.sendMsg(msg);
        return true;
    }
    public static void main(String[] args){
        start();
    }
}


服务端代码:
package com.example.demo.aio;

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;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2018/3/12
 * Time: 17:42
 * To change this template use File | Settings | File Templates.
 */
public class NioServer implements Runnable {
    private Selector selector;
    private ServerSocketChannel serverSocketChannel;
    private volatile boolean started;
    public NioServer(int port) throws IOException {
        //指定选择器
        selector = Selector.open();
        //打开监听通道
        serverSocketChannel = ServerSocketChannel.open();
        //设置监听通道是否为阻塞(true)/非阻塞(false)
        serverSocketChannel.configureBlocking(false);   //开启非阻塞模式
        //绑定端口, backlog设为1024
        serverSocketChannel.socket().bind(new InetSocketAddress(port),1024);
        //监听客户端连接请求
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        //标记服务器开启
        started = true;
        System.out.println("AioServer.AioServer已开启端口:"+port);

    }
     public void stop(){
         started =false;
     }
    @Override
    public void run() {
            //如果服务器开启
          while(started){
             //循环变量selector
              try {
                  //无论是否有读写事件发生,selector每隔1s被唤醒一次
                  selector.select(1000);
                  //阻塞,只有当至少一个注册的事件发生的时候才会继续.
//              selector.select();
                  Set<SelectionKey> set = selector.selectedKeys();
                  Iterator<SelectionKey> iterator = set.iterator();
                  SelectionKey key = null;
                  while(iterator.hasNext()){
                        key = iterator.next();
                        iterator.remove();;
                      handleInputSelectionKey(key);
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
    }

    public void handleInputSelectionKey(SelectionKey key) throws IOException {
            if(key.isValid()){
                //处理新接入的请求信息
                if(key.isAcceptable()){
                       ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                    //通过ServerSocketChannel的accept创建SocketChannel实例
                    //完成该操作意味着完成TCP三次握手,TCP物理链路正式建立
                    SocketChannel sc = ssc.accept();
                    sc.configureBlocking(false);//设置为非阻塞
                    //注册为读
                    sc.register(selector, SelectionKey.OP_READ);
                }
                //读消息
                if(key.isReadable()){
                     SocketChannel sc = (SocketChannel) key.channel();
                    //创建ByteBuffer,并开辟一个1M的缓冲区
                    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                    ////读取请求码流,返回读取到的字节数
                    int readbytes = sc.read(byteBuffer);
                    //读取到字节,对字节进行编解码
                    if(readbytes >0){
                        //将缓冲区当前的limit设置为position=0,用于后续对缓冲区的读取操作
                        byteBuffer.flip();
                        //根据缓冲区可读字节数创建字节数组
                        byte[] bytes = new byte[byteBuffer.remaining()];
                        //将缓冲区可读字节数组复制到新建的数组中
                        byteBuffer.get(bytes);
                        String msg = new String(bytes,"UTF-8");
                        System.out.println("服务器收到消息:" + msg);
                        //发送应答消息
                        String result = "收到"+msg;
                        doWrite(sc,msg);
                    }
                    //没有读取到字节 忽略
//              else if(readBytes==0);
                    //链路已经关闭,释放资源
                     else if(readbytes<0){
                        key.cancel();
                        sc.close();
                    }

                }
            }
    }
    //异步发送应答消息
    private void doWrite(SocketChannel channel,String response) throws IOException{
        //将消息编码为字节数组
        byte[] bytes = response.getBytes();
        //根据数组容量创建ByteBuffer
        ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
        //将字节数组复制到缓冲区
        writeBuffer.put(bytes);
        //flip操作
        writeBuffer.flip();
        //发送缓冲区的字节数组
        channel.write(writeBuffer);
        //****此处不含处理“写半包”的代码
    }
}


  


package com.example.demo.aio;

import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2018/3/12
 * Time: 18:12
 * To change this template use File | Settings | File Templates.
 */
public class RunServer {
    private final  static int PORT = 12345;
    private static NioServer nioServer;
    public static void start(){
        start(PORT);
    }
    public static synchronized void start(int port){
        if(aioServer!=null)
            nioServer.stop();
        try {
            nioServer = new NioServer(port);
        } catch (IOException e) {
            e.printStackTrace();
        }
        new Thread(nioServer,"Server").start();
    }
    public static void main(String[] args){
        start();
    }
}


测试代码:
package com.example.demo.aio;

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2018/3/13
 * Time: 10:07
 * To change this template use File | Settings | File Templates.
 */
public class NioTest {
    public static void main(String[] args) throws Exception {
        RunServer.start();
        Thread.sleep(1000);
        RunClient.start();
        RunClient.sendMsg("jsjsj");
//        while (RunClient.sendMsg(new Scanner(System.in).nextLine()));
    }
}


三、异步非阻塞AIO
   NIO 2.0引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。
    异步的套接字通道时真正的异步非阻塞I/O,对应于UNIX网络编程中的事件驱动I/O(AIO)。他不需要过多的Selector对注册的通道进行轮询即可实现异步读写,从而简化了NIO的编程模型。
  客户端代码:
package com.example.demo.aio;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.CountDownLatch;

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2018/3/12
 * Time: 18:15
 * To change this template use File | Settings | File Templates.
 */
public class AioClient implements CompletionHandler<Void, AioClient>, Runnable{

    private String ip;
    private int port;
    private AsynchronousSocketChannel asynchronousSocketChannel;
    private CountDownLatch latch;
    public AioClient(String ip,int port){
        this.ip=ip;
        this.port=port;
        try {
            //创建异步的客户端通道
            asynchronousSocketChannel = AsynchronousSocketChannel.open();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void run() {
        //创建CountDownLatch等待
        latch = new CountDownLatch(1);
        //发起异步连接操作,回调参数就是这个类本身,如果连接成功会回调completed方法
        asynchronousSocketChannel.connect(new InetSocketAddress(ip, port), this, this);
        try {
            latch.await();
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        try {
            asynchronousSocketChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //连接服务器成功
    //意味着TCP三次握手完成
    public void completed(Void result, AioClient attachment) {
        System.out.println("客户端成功连接到服务器...");
    }
    //连接服务器失败
    public void failed(Throwable exc, AioClient attachment) {
        System.err.println("连接服务器失败...");
        exc.printStackTrace();
        try {
            asynchronousSocketChannel.close();
            latch.countDown();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //向服务器发送消息
    public void sendMsg(String msg){
        byte[] req = msg.getBytes();
        ByteBuffer writeBuffer = ByteBuffer.allocate(req.length);
        writeBuffer.put(req);
        writeBuffer.flip();
        //异步写
        asynchronousSocketChannel.write(writeBuffer, writeBuffer,new WriteHandler(asynchronousSocketChannel, latch));
    }


}
class WriteHandler implements CompletionHandler<Integer, ByteBuffer> {
    private AsynchronousSocketChannel clientChannel;
    private CountDownLatch latch;
    public WriteHandler(AsynchronousSocketChannel clientChannel,CountDownLatch latch) {
        this.clientChannel = clientChannel;
        this.latch = latch;
    }
    public void completed(Integer result, ByteBuffer buffer) {
        //完成全部数据的写入
        if (buffer.hasRemaining()) {
            clientChannel.write(buffer, buffer, this);
        }
        else {
            //读取数据
            ByteBuffer readBuffer = ByteBuffer.allocate(1024);
            clientChannel.read(readBuffer,readBuffer,new ReadClientHandler(clientChannel, latch));
        }
    }
    public void failed(Throwable exc, ByteBuffer attachment) {
        System.err.println("数据发送失败...");
        try {
            clientChannel.close();
            latch.countDown();
        } catch (IOException e) {
        }
    }
}
class ReadClientHandler implements CompletionHandler<Integer, ByteBuffer> {
    private AsynchronousSocketChannel clientChannel;
    private CountDownLatch latch;
    public ReadClientHandler(AsynchronousSocketChannel clientChannel,CountDownLatch latch) {
        this.clientChannel = clientChannel;
        this.latch = latch;
    }
    @Override
    public void completed(Integer result,ByteBuffer buffer) {
        buffer.flip();
        byte[] bytes = new byte[buffer.remaining()];
        buffer.get(bytes);
        String body;
        try {
            body = new String(bytes,"UTF-8");
            System.out.println("客户端收到结果:"+ body);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void failed(Throwable exc,ByteBuffer attachment) {
        System.err.println("数据读取失败...");
        try {
            clientChannel.close();
            latch.countDown();
        } catch (IOException e) {
        }
    }
}

package com.example.demo.aio;

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2018/3/13
 * Time: 9:13
 * To change this template use File | Settings | File Templates.
 */
public class RunClient {
    private final static int DEFUALT_PORT=12345;
    private final static String SERVER_IP="127.0.0.1";
    private static AioClient aioClient;

    public static void start(){
        start(DEFUALT_PORT,SERVER_IP);
    }
    public synchronized static void start(int port,String ip){
        if(aioClient==null){
            aioClient = new AioClient(ip,port);
            new Thread(aioClient,"client").start();
        }
    }
    //向服务器发送消息
    public static boolean sendMsg(String msg) throws Exception{
        if(msg.equals("q")) return false;
        aioClient.sendMsg(msg);
        return true;
    }
    public static void main(String[] args){
        start();
    }
}

服务端代码:
package com.example.demo.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.util.concurrent.CountDownLatch;

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2018/3/12
 * Time: 17:42
 * To change this template use File | Settings | File Templates.
 */
public class AioServer implements Runnable {
    public CountDownLatch latch;
    public  AsynchronousServerSocketChannel asynchronousServerSocketChannel;
    public AioServer(int port) throws IOException {
        //创建服务通道
        asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open();
        //绑定端口
        asynchronousServerSocketChannel.bind(new InetSocketAddress(port),1024);
        //标记服务器开启
        System.out.println("AioServer.AioServer已开启端口:"+port);

    }
    public void run() {
        //CountDownLatch初始化
        //它的作用:在完成一组正在执行的操作之前,允许当前的现场一直阻塞
        //此处,让现场在此阻塞,防止服务端执行完成后退出
        //也可以使用while(true)+sleep
        //生成环境就不需要担心这个问题,以为服务端是不会退出的
        latch = new CountDownLatch(1);
        //用于接收客户端的连接
        asynchronousServerSocketChannel.accept(this,new AcceptHandler());
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
package com.example.demo.aio;

import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2018/3/13
 * Time: 11:35
 * To change this template use File | Settings | File Templates.
 */
//作为handler接收客户端连接
public class AcceptHandler implements CompletionHandler<AsynchronousSocketChannel, AioServer> {
    public void completed(AsynchronousSocketChannel channel,AioServer aioServer) {
        //继续接受其他客户端的请求
        RunServer.clientCount++;
        System.out.println("连接的客户端数:" + RunServer.clientCount);
        aioServer.asynchronousServerSocketChannel.accept(aioServer, this);
        //创建新的Buffer
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        //异步读  第三个参数为接收消息回调的业务Handler
        channel.read(buffer, buffer, new ReadHandler(channel));
    }
    public void failed(Throwable exc, AioServer aioServer) {
        exc.printStackTrace();
        aioServer.latch.countDown();
    }
}
package com.example.demo.aio;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2018/3/13
 * Time: 11:42
 * To change this template use File | Settings | File Templates.
 */
public class ReadHandler implements CompletionHandler<Integer, ByteBuffer> {
    //用于读取半包消息和发送应答
    private AsynchronousSocketChannel channel;
    public ReadHandler(AsynchronousSocketChannel channel) {
        this.channel = channel;
    }
    //读取到消息后的处理
    public void completed(Integer result, ByteBuffer attachment) {
        //flip操作
        attachment.flip();
        //根据
        byte[] message = new byte[attachment.remaining()];
        attachment.get(message);
        try {
            String expression = new String(message, "UTF-8");
            System.out.println("服务器收到消息: " + expression);

            //向客户端发送消息
            doWrite("服务器发送客户端:"+expression);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
    //发送消息
    private void doWrite(String result) {
        byte[] bytes = result.getBytes();
        ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
        writeBuffer.put(bytes);
        writeBuffer.flip();
        //异步写数据 参数与前面的read一样
        channel.write(writeBuffer, writeBuffer,new CompletionHandler<Integer, ByteBuffer>() {
            public void completed(Integer result, ByteBuffer buffer) {
                //如果没有发送完,就继续发送直到完成
                if (buffer.hasRemaining())
                    channel.write(buffer, buffer, this);
                else{
                    //创建新的Buffer
                    ByteBuffer readBuffer = ByteBuffer.allocate(1024);
                    //异步读  第三个参数为接收消息回调的业务Handler
                    channel.read(readBuffer, readBuffer, new ReadHandler(channel));
                }
            }
            public void failed(Throwable exc, ByteBuffer attachment) {
                try {
                    channel.close();
                } catch (IOException e) {
                }
            }
        });
    }
    public void failed(Throwable exc, ByteBuffer attachment) {
        try {
            this.channel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

package com.example.demo.aio;

import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2018/3/12
 * Time: 18:12
 * To change this template use File | Settings | File Templates.
 */
public class RunServer {
    private final  static int PORT = 12345;
    private static AioServer aioServer;
    public static int  clientCount =0;
    public static void start(){
        start(PORT);
    }
    public static synchronized void start(int port){
        if(aioServer != null){
            try {
                aioServer = new AioServer(port);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        new Thread(aioServer,"Server").start();
    }
    public static void main(String[] args){
        start();
    }
}


各种I/O的对比:

Java中BIO、NIO、AIO的原理及其区别
            
    
    博客分类: java java、IO、NIO、AIO
BIO、NIO、AIO适用场景分析:

    BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

    NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。

    AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

另外,I/O属于底层操作,需要操作系统支持,并发也需要操作系统的支持,所以性能方面不同操作系统差异会比较明显。

  • Java中BIO、NIO、AIO的原理及其区别
            
    
    博客分类: java java、IO、NIO、AIO
  • 大小: 25.6 KB
  • Java中BIO、NIO、AIO的原理及其区别
            
    
    博客分类: java java、IO、NIO、AIO
  • 大小: 9.3 KB
  • Java中BIO、NIO、AIO的原理及其区别
            
    
    博客分类: java java、IO、NIO、AIO
  • 大小: 36.8 KB
  • Java中BIO、NIO、AIO的原理及其区别
            
    
    博客分类: java java、IO、NIO、AIO
  • 大小: 44.9 KB
相关标签: java、IO、NIO、AIO