• java aio nio bio


    转自:http://blog.csdn.NET/liuxiao723846/article/details/45066095


    Java中的IO主要源自于网络和本地文件

     

         IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO

         在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服 务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒 绝请求,如果有的话,客户端会线程会等待请求结束后才继续执行。

     

         BIO与NIO一个比较重要的不同,是我们使用BIO的时候往往会引入多线程,每个连接一个单独的线程;而NIO则是使用单线程或者只使用少量的多线程,每个连接共用一个线程。


             NIO的最重要的地方是当一个连接创建后,不需要对应一个线程,这个连接会被注册到多路复用器上面,所以所有的连接只需要一个线程就可以搞定,当这个线程 中的多路复用器进行轮询的时候,发现连接上有请求的话,才开启一个线程进行处理,也就是一个请求一个线程模式。


     

            在NIO的处理方式中,当一个请求来的话,开启线程进行处理,可能会等待后端应用的资源(JDBC连接等),其实这个线程就被阻塞了,当并发上来的话,还是会有BIO一样的问题。

    AIO:  

        HTTP/1.1出现后,有了Http长连接,这样除了超时和指明特定关闭的http header外,这个链接是一直打开的状态的,这样在NIO处理中可以进一步的进化,在后端资源中可以实现资源池或者队列,当请求来的话,开启的线程把请 求和请求数据传送给后端资源池或者队列里面就返回,并且在全局的地方保持住这个现场(哪个连接的哪个请求等),这样前面的线程还是可以去接受其他的请求, 而后端的应用的处理只需要执行队列里面的就可以了,这样请求处理和后端应用是异步的.当后端处理完,到全局地方得到现场,产生响应,这个就实现了异步处 理。

     

         BIO是一个连接一个线程。

       NIO是一个请求一个线程。

       AIO是一个有效请求一个线程。


     

            大家都知道自从jdk5开始,java中多了java.nio和java.util.concurent包,这两个包可谓威力无穷啊,像tomcat最新版本(用了concurrent包),mina等纷纷在此基础上进行了更新(mina更是直接就通过java.nio来实现的)。其实nio说起来很简单。java通信的基础是socket.和serversocket 在此基础上封装一下,就是socketchannel和serversocketchannel,封装成channel的最大好处就是可以实现non-blocking的通信。然后再加入了一个多路轮询机制,通过观察者模式使得通过单线程就可以同时管理多个channel. 明白了这些之后,放出我的例子来。分别使用socket,channel,selector

    实现了java的通信。

     

    Server:

     

     
     

    import import import import import import import public TestChannel {    

    •    main(String args[])  IOException{    
    •         TestChannel tt= TestChannel();    
    •   
    •         tt.initSelector();    
    •   
    •       initServerSocket( port)  IOException{    
    •   
    •  ServerSocket(port);    
    •         (){    
    • [] buf= [];    
    •                 {    
    • (Exception ex){    
    •                     socket.close();    
    •  String(buf));    
    •   
    •   initServerChannel( port)  IOException{    
    •         ServerSocketChannel ssc=ServerSocketChannel.open();    
    • );    
    •         ServerSocket ss=ssc.socket();    
    •  InetSocketAddress(port));    
    •         (){    
    • (sc!=){    
    • [] buf= [];    
    •                 {    
    • (Exception ex){    
    •                     socket.close();    
    •  String(buf));    
    •   
    •   initSelector( port)  IOException{    
    •         Selector selector=Selector.open();    
    •   
    •         ServerSocketChannel ssc=ServerSocketChannel.open();    
    • );    
    •         ServerSocket ss=ssc.socket();    
    •  InetSocketAddress(port));    
    •         ssc.register(selector, SelectionKey.OP_ACCEPT);    
    • (){    
    •              interestNo=selector.select();    
    • (interestNo==)    
    •                 ;    
    • (SelectionKey key:keys){    
    •   
    •                 (key.isAcceptable()){    
    • {    
    • );    
    •                     sc.register(selector, SelectionKey.OP_READ);    
    • (Exception ex){    
    •  (key.isReadable()){    
    • );    
    • {    
    •                     sc.read(bbuf);    
    • (Exception ex){    
    •  String(bbuf.array()));    
    •                     keys.remove(key);    
    •     
    • ;    
    •     }  

     client:

     

     

     
     

    public TestChannelClient {    

    •    main(String args[])  UnknownHostException, IOException{    
    •  Socket(,);    
    •     OutputStream out=sc.getOutputStream();    
    • .getBytes());    
    •     out.flush();    
    • }    
  • 相关阅读:
    javascript DOM操作
    DirectX编译出现link错误
    PPT快捷键
    Windows GDI笔记
    VC++键盘消息
    VC++6.0快捷键
    C#值类型和引用类型
    C#转义字符
    关于C#里“浅表副本”的解释
    C#中override和overload的区别
  • 原文地址:https://www.cnblogs.com/xuyatao/p/6870311.html
Copyright © 2020-2023  润新知