`
lxy2330
  • 浏览: 468444 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java nio 2.0 AIO

 
阅读更多

 按照《Unix网络编程》的划分,IO模型可以分为:阻塞IO、非阻塞IO、IO复用、信号驱动IO和异步IO,按照POSIX标准来划分只分为两类:同步IO和异步IO。如何区分呢?首先一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作,同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO,因此阻塞IO、非阻塞IO、IO服用、信号驱动IO都是同步IO,如果不阻塞,而是操作系统帮你做完IO操作再将结果返回给你,那么就是异步IO。阻塞IO和非阻塞IO的区别在于第一步,发起IO请求是否会被阻塞,如果阻塞直到完成那么就是传统的阻塞IO,如果不阻塞,那么就是非阻塞IO。

   Java nio 2.0的主要改进就是引入了异步IO(包括文件和网络),这里主要介绍下异步网络IO API的使用以及框架的设计,以TCP服务端为例。首先看下为了支持AIO引入的新的类和接口:

 java.nio.channels.AsynchronousChannel
       标记一个channel支持异步IO操作。

 java.nio.channels.AsynchronousServerSocketChannel
       ServerSocket的aio版本,创建TCP服务端,绑定地址,监听端口等。

 java.nio.channels.AsynchronousSocketChannel
       面向流的异步socket channel,表示一个连接。

 java.nio.channels.AsynchronousChannelGroup
       异步channel的分组管理,目的是为了资源共享。一个AsynchronousChannelGroup绑定一个线程池,这个线程池执行两个任务:处理IO事件和派发CompletionHandler。AsynchronousServerSocketChannel创建的时候可以传入一个 AsynchronousChannelGroup,那么通过AsynchronousServerSocketChannel创建的 AsynchronousSocketChannel将同属于一个组,共享资源。

 java.nio.channels.CompletionHandler
       异步IO操作结果的回调接口,用于定义在IO操作完成后所作的回调工作。AIO的API允许两种方式来处理异步操作的结果:返回的Future模式或者注册CompletionHandler,我更推荐用CompletionHandler的方式,这些handler的调用是由 AsynchronousChannelGroup的线程池派发的。显然,线程池的大小是性能的关键因素。AsynchronousChannelGroup允许绑定不同的线程池,通过三个静态方法来创建:

Java代码 复制代码 收藏代码
  1. public static AsynchronousChannelGroup withFixedThreadPool(int nThreads,   
  2.                                                               ThreadFactory threadFactory)   
  3.        throws IOException   
  4.   
  5. public static AsynchronousChannelGroup withCachedThreadPool(ExecutorService executor,   
  6.                                                                int initialSize)   
  7.   
  8. public static AsynchronousChannelGroup withThreadPool(ExecutorService executor)   
  9.        throws IOException  
 public static AsynchronousChannelGroup withFixedThreadPool(int nThreads,
                                                               ThreadFactory threadFactory)
        throws IOException

 public static AsynchronousChannelGroup withCachedThreadPool(ExecutorService executor,
                                                                int initialSize)

 public static AsynchronousChannelGroup withThreadPool(ExecutorService executor)
        throws IOException

 

     需要根据具体应用相应调整,从框架角度出发,需要暴露这样的配置选项给用户。

     在介绍完了aio引入的TCP的主要接口和类之后,我们来设想下一个aio框架应该怎么设计。参考非阻塞nio框架的设计,一般都是采用Reactor模式,Reacot负责事件的注册、select、事件的派发;相应地,异步IO有个Proactor模式,Proactor负责 CompletionHandler的派发,查看一个典型的IO写操作的流程来看两者的区别:

     Reactor:  send(msg) -> 消息队列是否为空,如果为空  -> 向Reactor注册OP_WRITE,然后返回 -> Reactor select -> 触发Writable,通知用户线程去处理 ->先注销Writable(很多人遇到的cpu 100%的问题就在于没有注销),处理Writeable,如果没有完全写入,继续注册OP_WRITE。注意到,写入的工作还是用户线程在处理。
     Proactor: send(msg) -> 消息队列是否为空,如果为空,发起read异步调用,并注册CompletionHandler,然后返回。 -> 操作系统负责将你的消息写入,并返回结果(写入的字节数)给Proactor -> Proactor派发CompletionHandler。可见,写入的工作是操作系统在处理,无需用户线程参与。事实上在aio的API 中,AsynchronousChannelGroup就扮演了Proactor的角色

    CompletionHandler有三个方法,分别对应于处理成功、失败、被取消(通过返回的Future)情况下的回调处理:

Java代码 复制代码 收藏代码
  1. public interface CompletionHandler<V,A> {   
  2.   
  3.      void completed(V result, A attachment);   
  4.   
  5.     void failed(Throwable exc, A attachment);   
  6.   
  7.       
  8.     void cancelled(A attachment);   
  9. }  
public interface CompletionHandler<V,A> {

     void completed(V result, A attachment);

    void failed(Throwable exc, A attachment);

   
    void cancelled(A attachment);
}

 


    其中的泛型参数V表示IO调用的结果,而A是发起调用时传入的attchment。

    在初步介绍完aio引入的类和接口后,我们看看一个典型的tcp服务端是怎么启动的,怎么接受连接并处理读和写,这里引用的代码都是yanf4j 的aio分支中的代码,可以从svn checkout,svn地址: http://yanf4j.googlecode.com/svn/branches/yanf4j-aio

    第一步,创建一个AsynchronousServerSocketChannel,创建之前先创建一个 AsynchronousChannelGroup,上文提到AsynchronousServerSocketChannel可以绑定一个 AsynchronousChannelGroup,那么通过这个AsynchronousServerSocketChannel建立的连接都将同属于一个AsynchronousChannelGroup并共享资源:

Java代码 复制代码 收藏代码
  1. this.asynchronousChannelGroup = AsynchronousChannelGroup   
  2.                     .withCachedThreadPool(Executors.newCachedThreadPool(),   
  3.                             this.threadPoolSize);  
this.asynchronousChannelGroup = AsynchronousChannelGroup
                    .withCachedThreadPool(Executors.newCachedThreadPool(),
                            this.threadPoolSize);

     然后初始化一个AsynchronousServerSocketChannel,通过open方法:

Java代码 复制代码 收藏代码
  1. this.serverSocketChannel = AsynchronousServerSocketChannel   
  2.                 .open(this.asynchronousChannelGroup);  
this.serverSocketChannel = AsynchronousServerSocketChannel
                .open(this.asynchronousChannelGroup);

 

    通过nio 2.0引入的SocketOption类设置一些TCP选项:

Java代码 复制代码 收藏代码
  1. this.serverSocketChannel   
  2.                     .setOption(   
  3.                             StandardSocketOption.SO_REUSEADDR,true);   
  4. this.serverSocketChannel   
  5.                     .setOption(   
  6.                             StandardSocketOption.SO_RCVBUF,16*1024);  
this.serverSocketChannel
                    .setOption(
                            StandardSocketOption.SO_REUSEADDR,true);
this.serverSocketChannel
                    .setOption(
                            StandardSocketOption.SO_RCVBUF,16*1024);

 


    绑定本地地址:

Java代码 复制代码 收藏代码
  1. this.serverSocketChannel   
  2.                     .bind(new InetSocketAddress("localhost",8080), 100);  
this.serverSocketChannel
                    .bind(new InetSocketAddress("localhost",8080), 100);

 

  
    其中的100用于指定等待连接的队列大小(backlog)。完了吗?还没有,最重要的监听工作还没开始,监听端口是为了等待连接上来以便accept产生一个AsynchronousSocketChannel来表示一个新建立的连接,因此需要发起一个accept调用,调用是异步的,操作系统将在连接建立后,将最后的结果——AsynchronousSocketChannel返回给你:

Java代码 复制代码 收藏代码
  1. public void pendingAccept() {   
  2.         if (this.started && this.serverSocketChannel.isOpen()) {   
  3.             this.acceptFuture = this.serverSocketChannel.accept(null,   
  4.                     new AcceptCompletionHandler());   
  5.   
  6.         } else {   
  7.             throw new IllegalStateException("Controller has been closed");   
  8.         }   
  9.     }  
public void pendingAccept() {
        if (this.started && this.serverSocketChannel.isOpen()) {
            this.acceptFuture = this.serverSocketChannel.accept(null,
                    new AcceptCompletionHandler());

        } else {
            throw new IllegalStateException("Controller has been closed");
        }
    }

 


   注意,重复的accept调用将会抛出PendingAcceptException,后文提到的read和write也是如此。accept方法的第一个参数是你想传给CompletionHandler的attchment,第二个参数就是注册的用于回调的CompletionHandler,最后返回结果Future<AsynchronousSocketChannel>。你可以对future做处理,这里采用更推荐的方式就是注册一个CompletionHandler。那么accept的CompletionHandler中做些什么工作呢?显然一个赤裸裸的 AsynchronousSocketChannel是不够的,我们需要将它封装成session,一个session表示一个连接(mina里就叫 IoSession了),里面带了一个缓冲的消息队列以及一些其他资源等。在连接建立后,除非你的服务器只准备接受一个连接,不然你需要在后面继续调用pendingAccept来发起另一个accept请求

Java代码 复制代码 收藏代码
  1. private final class AcceptCompletionHandler implements  
  2.             CompletionHandler<AsynchronousSocketChannel, Object> {   
  3.   
  4.         @Override  
  5.         public void cancelled(Object attachment) {   
  6.             logger.warn("Accept operation was canceled");   
  7.         }   
  8.   
  9.         @Override  
  10.         public void completed(AsynchronousSocketChannel socketChannel,   
  11.                 Object attachment) {   
  12.             try {   
  13.                 logger.debug("Accept connection from "  
  14.                         + socketChannel.getRemoteAddress());   
  15.                 configureChannel(socketChannel);   
  16.                 AioSessionConfig sessionConfig = buildSessionConfig(socketChannel);   
  17.                 Session session = new AioTCPSession(sessionConfig,   
  18.                         AioTCPController.this.configuration   
  19.                                 .getSessionReadBufferSize(),   
  20.                         AioTCPController.this.sessionTimeout);   
  21.                 session.start();   
  22.                 registerSession(session);   
  23.             } catch (Exception e) {   
  24.                 e.printStackTrace();   
  25.                 logger.error("Accept error", e);   
  26.                 notifyException(e);   
  27.             } finally {   
  28.                 <STRONG>pendingAccept</STRONG>();   
  29.             }   
  30.         }   
  31.   
  32.         @Override  
  33.         public void failed(Throwable exc, Object attachment) {   
  34.             logger.error("Accept error", exc);   
  35.             try {   
  36.                 notifyException(exc);   
  37.             } finally {   
  38.                 <STRONG>pendingAccept</STRONG>();   
  39.             }   
  40.         }   
  41.     }  
private final class AcceptCompletionHandler implements
            CompletionHandler<AsynchronousSocketChannel, Object> {

        @Override
        public void cancelled(Object attachment) {
            logger.warn("Accept operation was canceled");
        }

        @Override
        public void completed(AsynchronousSocketChannel socketChannel,
                Object attachment) {
            try {
                logger.debug("Accept connection from "
                        + socketChannel.getRemoteAddress());
                configureChannel(socketChannel);
                AioSessionConfig sessionConfig = buildSessionConfig(socketChannel);
                Session session = new AioTCPSession(sessionConfig,
                        AioTCPController.this.configuration
                                .getSessionReadBufferSize(),
                        AioTCPController.this.sessionTimeout);
                session.start();
                registerSession(session);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("Accept error", e);
                notifyException(e);
            } finally {
                pendingAccept();
            }
        }

        @Override
        public void failed(Throwable exc, Object attachment) {
            logger.error("Accept error", exc);
            try {
                notifyException(exc);
            } finally {
                pendingAccept();
            }
        }
    }

 

 
    注意到了吧,我们在failed和completed方法中在最后都调用了pendingAccept来继续发起accept调用,等待新的连接上来。有的同学可能要说了,这样搞是不是递归调用,会不会堆栈溢出?实际上不会,因为发起accept调用的线程与CompletionHandler回调的线程并非同一个,不是一个上下文中,两者之间没有耦合关系。要注意到,CompletionHandler的回调共用的是 AsynchronousChannelGroup绑定的线程池,因此千万别在CompletionHandler回调方法中调用阻塞或者长时间的操作,例如sleep,回调方法最好能支持超时,防止线程池耗尽。

    连接建立后,怎么读和写呢?回忆下在nonblocking nio框架中,连接建立后的第一件事是干什么?注册OP_READ事件等待socket可读。异步IO也同样如此,连接建立后马上发起一个异步read调用,等待socket可读,这个是Session.start方法中所做的事情:

Java代码 复制代码 收藏代码
  1. public class AioTCPSession {   
  2.     protected void start0() {   
  3.         pendingRead();   
  4.     }   
  5.   
  6.     protected final void pendingRead() {   
  7.         if (!isClosed() && this.asynchronousSocketChannel.isOpen()) {   
  8.             if (!this.readBuffer.hasRemaining()) {   
  9.                 this.readBuffer = ByteBufferUtils   
  10.                         .increaseBufferCapatity(this.readBuffer);   
  11.             }   
  12.             this.readFuture = this.asynchronousSocketChannel.read(   
  13.                     this.readBuffer, thisthis.readCompletionHandler);   
  14.         } else {   
  15.             throw new IllegalStateException(   
  16.                     "Session Or Channel has been closed");   
  17.         }   
  18.     }   
  19.       
  20. }  
public class AioTCPSession {
    protected void start0() {
        pendingRead();
    }

    protected final void pendingRead() {
        if (!isClosed() && this.asynchronousSocketChannel.isOpen()) {
            if (!this.readBuffer.hasRemaining()) {
                this.readBuffer = ByteBufferUtils
                        .increaseBufferCapatity(this.readBuffer);
            }
            this.readFuture = this.asynchronousSocketChannel.read(
                    this.readBuffer, this, this.readCompletionHandler);
        } else {
            throw new IllegalStateException(
                    "Session Or Channel has been closed");
        }
    }
   
}

 

     AsynchronousSocketChannel的read调用与AsynchronousServerSocketChannel的accept调用类似,同样是非阻塞的,返回结果也是一个Future,但是写的结果是整数,表示写入了多少字节,因此read调用返回的是 Future<Integer>,方法的第一个参数是读的缓冲区,操作系统将IO读到数据拷贝到这个缓冲区,第二个参数是传递给 CompletionHandler的attchment,第三个参数就是注册的用于回调的CompletionHandler。这里保存了read的结果Future,这是为了在关闭连接的时候能够主动取消调用,accept也是如此。现在可以看看read的CompletionHandler的实现:

Java代码 复制代码 收藏代码
  1. public final class ReadCompletionHandler implements  
  2.         CompletionHandler<Integer, AbstractAioSession> {   
  3.   
  4.     private static final Logger log = LoggerFactory   
  5.             .getLogger(ReadCompletionHandler.class);   
  6.     protected final AioTCPController controller;   
  7.   
  8.     public ReadCompletionHandler(AioTCPController controller) {   
  9.         this.controller = controller;   
  10.     }   
  11.   
  12.     @Override  
  13.     public void cancelled(AbstractAioSession session) {   
  14.         log.warn("Session(" + session.getRemoteSocketAddress()   
  15.                 + ") read operation was canceled");   
  16.     }   
  17.   
  18.     @Override  
  19.     public void completed(Integer result, AbstractAioSession session) {   
  20.         if (log.isDebugEnabled())   
  21.             log.debug("Session(" + session.getRemoteSocketAddress()   
  22.                     + ") read +" + result + " bytes");   
  23.         if (result < 0) {   
  24.             session.close();   
  25.             return;   
  26.         }   
  27.         try {   
  28.             if (result > 0) {   
  29.                 session.updateTimeStamp();   
  30.                 session.getReadBuffer().flip();   
  31.                 session.decode();   
  32.                 session.getReadBuffer().compact();   
  33.             }   
  34.         } finally {   
  35.             try {   
  36.                 session.pendingRead();   
  37.             } catch (IOException e) {   
  38.                 session.onException(e);   
  39.                 session.close();   
  40.             }   
  41.         }   
  42.         controller.checkSessionTimeout();   
  43.     }   
  44.   
  45.     @Override  
  46.     public void failed(Throwable exc, AbstractAioSession session) {   
  47.         log.error("Session read error", exc);   
  48.         session.onException(exc);   
  49.         session.close();   
  50.     }   
  51.   
  52. }  
public final class ReadCompletionHandler implements
        CompletionHandler<Integer, AbstractAioSession> {

    private static final Logger log = LoggerFactory
            .getLogger(ReadCompletionHandler.class);
    protected final AioTCPController controller;

    public ReadCompletionHandler(AioTCPController controller) {
        this.controller = controller;
    }

    @Override
    public void cancelled(AbstractAioSession session) {
        log.warn("Session(" + session.getRemoteSocketAddress()
                + ") read operation was canceled");
    }

    @Override
    public void completed(Integer result, AbstractAioSession session) {
        if (log.isDebugEnabled())
            log.debug("Session(" + session.getRemoteSocketAddress()
                    + ") read +" + result + " bytes");
        if (result < 0) {
            session.close();
            return;
        }
        try {
            if (result > 0) {
                session.updateTimeStamp();
                session.getReadBuffer().flip();
                session.decode();
                session.getReadBuffer().compact();
            }
        } finally {
            try {
                session.pendingRead();
            } catch (IOException e) {
                session.onException(e);
                session.close();
            }
        }
        controller.checkSessionTimeout();
    }

    @Override
    public void failed(Throwable exc, AbstractAioSession session) {
        log.error("Session read error", exc);
        session.onException(exc);
        session.close();
    }

}

 

   如果IO读失败,会返回失败产生的异常,这种情况下我们就主动关闭连接,通过session.close()方法,这个方法干了两件事情:关闭channel和取消read调用:

Java代码 复制代码 收藏代码
  1. if (null != this.readFuture) {   
  2.             this.readFuture.cancel(true);   
  3.         }   
  4. this.asynchronousSocketChannel.close();  
if (null != this.readFuture) {
            this.readFuture.cancel(true);
        }
this.asynchronousSocketChannel.close();

 

   在读成功的情况下,我们还需要判断结果result是否小于0,如果小于0就表示对端关闭了,这种情况下我们也主动关闭连接并返回。如果读到一定字节,也就是result大于0的情况下,我们就尝试从读缓冲区中decode出消息,并派发给业务处理器的回调方法,最终通过pendingRead继续发起read调用等待socket的下一次可读。可见,我们并不需要自己去调用channel来进行IO读,而是操作系统帮你直接读到了缓冲区,然后给你一个结果表示读入了多少字节,你处理这个结果即可。而nonblocking IO框架中,是reactor通知用户线程socket可读了,然后用户线程自己去调用read进行实际读操作。这里还有个需要注意的地方,就是decode出来的消息的派发给业务处理器工作最好交给一个线程池来处理,避免阻塞group绑定的线程池。
 
   IO写的操作与此类似,不过通常写的话我们会在session中关联一个缓冲队列来处理,没有完全写入或者等待写入的消息都存放在队列中,队列为空的情况下发起write调用:

Java代码 复制代码 收藏代码
  1. protected void write0(WriteMessage message) {   
  2.       boolean needWrite = false;   
  3.       synchronized (this.writeQueue) {   
  4.           needWrite = this.writeQueue.isEmpty();   
  5.           this.writeQueue.offer(message);   
  6.       }   
  7.       if (needWrite) {   
  8.           pendingWrite(message);   
  9.       }   
  10.   }   
  11.   
  12.   protected final void pendingWrite(WriteMessage message) {   
  13.       message = preprocessWriteMessage(message);   
  14.       if (!isClosed() && this.asynchronousSocketChannel.isOpen()) {   
  15.           this.asynchronousSocketChannel.write(message.getWriteBuffer(),   
  16.                   thisthis.writeCompletionHandler);   
  17.       } else {   
  18.           throw new IllegalStateException(   
  19.                   "Session Or Channel has been closed");   
  20.       }   
  21.   }  
  protected void write0(WriteMessage message) {
        boolean needWrite = false;
        synchronized (this.writeQueue) {
            needWrite = this.writeQueue.isEmpty();
            this.writeQueue.offer(message);
        }
        if (needWrite) {
            pendingWrite(message);
        }
    }

    protected final void pendingWrite(WriteMessage message) {
        message = preprocessWriteMessage(message);
        if (!isClosed() && this.asynchronousSocketChannel.isOpen()) {
            this.asynchronousSocketChannel.write(message.getWriteBuffer(),
                    this, this.writeCompletionHandler);
        } else {
            throw new IllegalStateException(
                    "Session Or Channel has been closed");
        }
    }

 

    write调用返回的结果与read一样是一个Future<Integer>,而write的CompletionHandler处理的核心逻辑大概是这样:

Java代码 复制代码 收藏代码
  1. @Override  
  2.     public void completed(Integer result, AbstractAioSession session) {   
  3.         if (log.isDebugEnabled())   
  4.             log.debug("Session(" + session.getRemoteSocketAddress()   
  5.                     + ") writen " + result + " bytes");   
  6.                    
  7.         WriteMessage writeMessage;   
  8.         Queue<WriteMessage> writeQueue = session.getWriteQueue();   
  9.         synchronized (writeQueue) {   
  10.             writeMessage = writeQueue.peek();   
  11.             if (writeMessage.getWriteBuffer() == null  
  12.                     || !writeMessage.getWriteBuffer().hasRemaining()) {   
  13.                 writeQueue.remove();   
  14.                 if (writeMessage.getWriteFuture() != null) {   
  15.                     writeMessage.getWriteFuture().setResult(Boolean.TRUE);   
  16.                 }   
  17.                 try {   
  18.                     session.getHandler().onMessageSent(session,   
  19.                             writeMessage.getMessage());   
  20.                 } catch (Exception e) {   
  21.                     session.onException(e);   
  22.                 }   
  23.                 writeMessage = writeQueue.peek();   
  24.             }   
  25.         }   
  26.         if (writeMessage != null) {   
  27.             try {   
  28.                 session.pendingWrite(writeMessage);   
  29.             } catch (IOException e) {   
  30.                 session.onException(e);   
  31.                 session.close();   
  32.             }   
  33.         }   
  34.     }  
@Override
    public void completed(Integer result, AbstractAioSession session) {
        if (log.isDebugEnabled())
            log.debug("Session(" + session.getRemoteSocketAddress()
                    + ") writen " + result + " bytes");
                
        WriteMessage writeMessage;
        Queue<WriteMessage> writeQueue = session.getWriteQueue();
        synchronized (writeQueue) {
            writeMessage = writeQueue.peek();
            if (writeMessage.getWriteBuffer() == null
                    || !writeMessage.getWriteBuffer().hasRemaining()) {
                writeQueue.remove();
                if (writeMessage.getWriteFuture() != null) {
                    writeMessage.getWriteFuture().setResult(Boolean.TRUE);
                }
                try {
                    session.getHandler().onMessageSent(session,
                            writeMessage.getMessage());
                } catch (Exception e) {
                    session.onException(e);
                }
                writeMessage = writeQueue.peek();
            }
        }
        if (writeMessage != null) {
            try {
                session.pendingWrite(writeMessage);
            } catch (IOException e) {
                session.onException(e);
                session.close();
            }
        }
    }

 


   compete方法中的result就是实际写入的字节数,然后我们判断消息的缓冲区是否还有剩余,如果没有就将消息从队列中移除,如果队列中还有消息,那么继续发起write调用。

   重复一下,这里引用的代码都是yanf4j aio分支中的源码,感兴趣的朋友可以直接check out出来看看: http://yanf4j.googlecode.com/svn/branches/yanf4j-aio
   在引入了aio之后,java对于网络层的支持已经非常完善,该有的都有了,java也已经成为服务器开发的首选语言之一。java的弱项在于对内存的管理上,由于这一切都交给了GC,因此在高性能的网络服务器上还是Cpp的天下。java这种单一堆模型比之erlang的进程内堆模型还是有差距,很难做到高效的垃圾回收和细粒度的内存管理。

   这里仅仅是介绍了aio开发的核心流程,对于一个网络框架来说,还需要考虑超时的处理、缓冲buffer的处理、业务层和网络层的切分、可扩展性、性能的可调性以及一定的通用性要求。

分享到:
评论
1 楼 a939639017 2014-10-15  
yanf4j check不下来 ?

相关推荐

    利用JDK7的NIO2.0进行I/O读写和监视

    在Java编程领域,JDK 7引入了一个重要的更新——NIO2.0,也被称为“New I/O 2.0”或“AIO”(Asynchronous I/O)。这个更新极大地提升了Java处理I/O操作的能力,特别是在文件系统交互和网络通信方面。NIO2.0主要增加...

    异步输入/输出aio.doc

    异步输入/输出(Asynchronous Input/Output,简称AIO),是计算机系统中的一...Java NIO 2.0中的AIO支持为开发高性能、高并发的网络应用提供了便利。在设计AIO框架时,理解并合理运用这些核心概念和组件是至关重要的。

    Java2.0网络多线程编程实例教程(光盘源代码)

    此外,NIO(非阻塞I/O)在Java 2.0中被引入,提供了一种更高效、低延迟的I/O模型,适用于处理大量并发连接。 多线程编程则是Java的一大特色,它允许程序同时执行多个任务,提高了应用程序的效率和响应性。Java中的...

    getty:一个完全基于java的,类似netty的高性能网络框架A fully Java-based, netty - like high-performance networking framework

    Getty is a high-performance networking framework based entirely on Java NIO encapsulation. 2、getty可在项目中使用,也可以用于帮助你更好的学习java nio Getty can be used in a project or to help you ...

    Java 基础核心总结 +经典算法大全.rar

    BIO NIO 和 AIO 的区别什么是流 流的分类 节点流和处理流 Java IO 的核心类 File Java IO 流对象 字节流对象InputStream OutputStream 字符流对象Reader Writer 字节流与字符流的转换新潮的 NIO 缓冲区(Buffer)通道...

    探索Java I/O 模型的演进

    3. **NIO 2(AIO或NIO 2.0)**:Java 7引入了NIO的增强版,支持异步I/O操作,如AsynchronousServerSocketChannel和AsynchronousSocketChannel,使得开发者可以更方便地实现异步I/O。 在选择合适的Java I/O模型时,...

    threadmodel:java线程模型

    4. **AIO(Asynchronous I/O)模型或NIO 2.0**:进一步优化了I/O模型,提供了异步非阻塞的I/O操作,使得应用在等待数据准备时可以去做其他事情,提高了系统的吞吐量。 5. **线程池最佳实践**:如何根据实际需求调整...

    Java基础总结下1

    Java的IO模型主要包括三种:BIO(Blocking I/O)、NIO(Non-blocking I/O)和AIO(Asynchronous I/O)。BIO是最传统的同步阻塞模式,适合连接数量较少且活跃度高的场景;NIO是一种基于通道(Channel)和缓冲区(Buffer)...

    JDK7新特性(完整篇)

    4. **JDK7新特性&lt;四&gt; NIO2.0 文件系统** NIO2(非阻塞I/O的第二版)带来了全新的文件系统接口,包括Path API、WatchService API等,提供了异步文件操作和文件事件监听的能力,极大地提升了文件操作的灵活性和性能。...

    Java后端技术面试基础汇总

    - **BIO、NIO、AIO**:阻塞I/O、非阻塞I/O、异步I/O。 - **长连接和短连接**:长连接建立后持续使用,短连接每次请求重新建立。 - **HTTP1.0和2.0的区别**:二进制格式、多路复用、头部压缩等。 - **HTTPS的基本...

    野火聊天推送服务器_Java_下载.zip

    此外,服务器可能利用了Java的异步I/O模型,如NIO(非阻塞I/O)或者AIO(异步I/O),以提高效率。这些模型允许服务器在等待数据读写时不必阻塞其他任务,从而提高资源利用率和系统性能。 在消息推送方面,服务器...

    大型分布式网站架构设计与实践-高清完整版

    常见的解决方案包括负载均衡、缓存技术(如Redis和Memcached)、非阻塞I/O(如NIO和AIO)以及线程池管理。此外,采用异步处理和事件驱动模型也能有效提高并发性能。 3. **分布式架构**:分布式架构包括但不限于服务...

    Java后端技术面试汇总-2019

    - **BIO、NIO、AIO的概念**: - **BIO**:同步阻塞I/O。 - **NIO**:同步非阻塞I/O。 - **AIO**:异步非阻塞I/O。 - **长连接和短连接**: - **长连接**:保持TCP连接不断开。 - **短连接**:每次请求建立新...

    通过Socket传送文件的例子

    为了提高效率和可靠性,还可以考虑使用非阻塞I/O(NIO)或者异步I/O(AIO)进行优化。 总之,Socket编程是实现客户端和服务器之间通信的基础,通过它可以实现文件的高效传输。实际应用中,根据具体需求,可以对上述...

    gongyz-wxapp-little-shelf-master_springboot聊天_springboot_LittleM

    2. **Netty框架**:理解Netty的工作原理,包括BIO、NIO、AIO的区别,以及Netty的Channel、EventLoop、Handler等核心概念。 3. **WebSocket通信**:学习WebSocket协议,实现服务器与客户端的双向通信。 4. **数据库...

    java:java高级学习,主要包括并发编程,设计模式,性能优化,源码分析,微服务框架,高性能Nginx服务器,互联网高并发解决方案,互联网安全架构,分布式架构,分布式协调工具,分布式解决方案方案

    7. **互联网高并发解决方案**:面对大量用户请求,需要掌握如何处理高并发,如使用异步非阻塞IO(NIO、AIO)、消息队列(如RabbitMQ、Kafka)进行流量削峰填谷,以及数据库分库分表等策略。 8. **互联网安全架构**...

    铭洲网络后台解决方案-ccmingzhou.zip

    例如,可能会使用NIO(非阻塞I/O)或AIO(异步I/O)来提升服务器处理能力,同时结合线程池管理,确保系统资源的有效利用。 其次,关于Java部分,这个解决方案可能基于Spring Boot或者Spring Cloud框架,提供微服务...

    AmberServer:琥珀色服务器 + 网络服务器

    AmberServer可能采用了常见的服务器架构,如事件驱动模型(如NIO或AIO)或基于工作进程的模型。这些架构设计允许服务器高效地处理I/O操作,减少系统资源的占用,提高服务性能。事件驱动模型利用Java的Selector和...

    JavaSE基础面试题.docx

    39. **BIO、NIO、AIO**:BIO是同步阻塞,NIO是同步非阻塞,AIO(又称NIO.2)是异步非阻塞。 40. **数据库索引**:索引是一种数据结构,用于加速查询。B+树是常见的索引实现。 41. **数据库约束**:包括NOT NULL、...

    写一个迷你版的Tomcat.docx

    关于Socket的实现方式,Tomcat可以采用BIO(Blocking I/O)、NIO(Non-blocking I/O)或AIO(Asynchronous I/O)等不同的模型,这取决于具体的应用场景和需求。 #### 四、请求分发 考虑到Tomcat能够为多个Web应用...

Global site tag (gtag.js) - Google Analytics