文档章节

java nio 基本知识

o
 ovirtKg
发布于 2016/11/09 09:43
字数 659
阅读 11
收藏 1

我们知道javanio 底层实现是通过epoll系统调用实现,IO复用,简单来说就是一个Thread可以处理多个Channel。效率比传统的阻塞IO 一个线程只能处理一个Channel要高太多。

JAVA nio的核心  Channel  Buffer  Selector

Channel   

常用的Channel: FileChannel(文件) DatagramChannel (UDP)SocketChannel(通过TCP读写数据) ServerSocketChannel (监听TCP连接) 等,核心是处理IO读写操作。需要通过 Buffer 才能读写数据。

Buffer

对应java的8种基本数据类型都有相应的Buffer,  最为关键的是三个属性 limit,position,capacity 

limit表示 读写的限制,position表示 读写当前的位置,capacity表示缓冲区大小。

以ByteBuff 为例 

try {
            RandomAccessFile file = new RandomAccessFile("test.txt","rw");
            FileChannel fc = file.getChannel();
            ByteBuffer byteBuffer = ByteBuffer.allocate(10);
            try {
                int readint = fc.read(byteBuffer);

                while(readint!=-1){
                    System.out.println(" this times read : "+readint);
                    byteBuffer.flip();  //置pos位0,limit位之前pos位置
                    String bb = new String(byteBuffer.array());  //读取全部数据
                    while(byteBuffer.hasRemaining()){
                        System.out.print((char) byteBuffer.get()); //读取一个字节
                    }
                    byteBuffer.clear();  //清空
                    readint = fc.read(byteBuffer); //写缓冲区

                }
            } catch (IOException e) {
                e.printStackTrace();

            }
            try {
                fc.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

写数据到Buffer有两种方式:

  • 从Channel写到Buffer。 如上代码
  • 通过Buffer的put()方法写到Buffer里      byteBuffer.put(11);

从Buffer中读取数据有两种方式:

  • 从Buffer读取数据到Channel    channel.write(byteBuffer)
  • 使用get()方法从Buffer中读取数据。   如上代码

Selector

选择器,用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。selector中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接。

常用套路如下:

channel 在selector注册相应事件后,等待。循环如下。

Selector selector = Selector.open();
channel.configureBlocking(false);
SelectionKey key = channel.register(selector,
    Selectionkey.OP_READ);

while(true){
      selector.select();//阻塞,等待事件
      Set selectedKeys = selector.selectedKeys();
      Iterator keyIterator = selectedKeys.iterator();
      while(keyIterator.hasNext()) {
         SelectionKey key = keyIterator.next();
         if(key.isAcceptable()) {
        // a connection was accepted by a ServerSocketChannel.
         } else if (key.isConnectable()) {
        // a connection was established with a remote server.
         } else if (key.isReadable()) {
        // a channel is ready for reading
         } else if (key.isWritable()) {
        // a channel is ready for writing
         }
         keyIterator.remove();
      }
}

通道触发了一个事件意思是该事件已经就绪。所以,某个channel成功连接到另一个服务器称为“连接就绪”。一个server socket channel准备好接收新进入的连接称为“接收就绪”。一个有数据可读的通道可以说是“读就绪”。等待写数据的通道可以说是“写就绪”。

这四种事件用SelectionKey的四个常量来表示:

  1. SelectionKey.OP_CONNECT    1
  2. SelectionKey.OP_ACCEPT        4
  3. SelectionKey.OP_READ             8
  4. SelectionKey.OP_WRITE            16

 

 

http://ifeve.com/overview/

https://yq.aliyun.com/articles/2371

 

© 著作权归作者所有

o
粉丝 3
博文 57
码字总数 48798
作品 0
景德镇
私信 提问
Java网络编程框架

自从JDK1.4中有了NIO以后,这个方面越来越活跃,也为java赢得更多开发者的支持。做java网络编程需要掌握一些基本的知识和技能: 套接字编程、阻塞/非阻塞通信、创建HTTP服务器与客户程序、数...

长平狐
2012/08/29
2.3K
0
跳槽时,这些Java面试题99%会被问到

我在 Oracle 已经工作了近 7 年,面试过从初级到非常资深的Java工程师,且由于 Java 组工作任务的特点,我非常注重面试者的计算机科学基础和编程语言的理解深度,可以不要求面试者非要精通 ...

Java小铺
2018/08/15
0
0
php程序员, java程序员, ruby程序员

由于php入门很简单, 很多没任何编程背景的同学, 想学学怎么做网页的人基本一开始都会找php. php里不是菜鸟就是牛人. 菜鸟: 做做个人网页, 改改页面, 就学些php的基本东西就够用了. win环境下...

大东哥
2012/05/20
1K
12
BAT等公司必问的8道Java经典面试题,你都会了吗?

工作多年以及在面试中,我经常能体会到,有些面试者确实是认真努力工作,但坦白说表现出的能力水平却不足以通过面试,通常是两方面原因: 1、“知其然不知其所以然”。做了多年技术,开发了很...

java填坑路
01/06
0
0
这样的,求带走

现在研二上学期, 三年制,想寻求一份java后端开发的工作 有过将近两年在公司实习的经历 研究方向是分布式系统,soa服务化框架,有过开发服务集成平台的经历 java方面基本的语法之类的就不说了...

bii
2014/12/05
954
7

没有更多内容

加载失败,请刷新页面

加载更多

重定向与转发,绝对路径

/** 1. 请求和响应 * 请求:客户端向服务器 * 类型:HttpServletRequest request * 定义:代表了客户端向服务器发送的请求报文,该对象由服务器(web容器|Servlet容器)...

architect刘源源
19分钟前
1
0
node后端使用jwt实现跨域认证--生成token、验证token是否无效和过期

JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案 引入jwt var jwt = require('jsonwebtoken'); 生成token 在登录时,如果用户名和密码正确,则使用jwt生成token,返回给前端 le...

祖达
33分钟前
1
0
Oauth2 单点登陆

少年已不再年少
38分钟前
2
0
怎么做到有效沟通?

关于有效沟通,用下面两个场景来讲述一下: 情景1: 开发A:tickets库连不上,帮忙看一下。 运维:tikets库?国内、国外?什么环境?(测试、线上) 开发A:国外、测试 运维:在哪连接的?(...

阿dai学长
40分钟前
1
0
idea如何部署tomcat

最近在学习使用idea,有很多不习惯,这里记录一下tomcat的部署。 首先需要借助工具栏,需要在view(视图)中勾选工具栏和工具按钮,如下图: 然后点击选择[运行/调试]配置的按钮,如图所示: ...

我叫小糖主
55分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部