博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java nio
阅读量:4612 次
发布时间:2019-06-09

本文共 3821 字,大约阅读时间需要 12 分钟。

java nio是从java 1.4版本开始引入的。Java NIO和IO之间最大的区别:IO是面向流的,NIO是面向缓冲区的。nio核心组件:channel buffer selector三大组件

java io适用场景(原文链接:http://tutorials.jenkov.com/java-nio/overview.html):

1、并发量较小;

2、单连接一次发送数据包较大(要求内存足够,此读写线程阻塞);

java nio适用场景:

1、并发量较大;

2、单连接一次发送数据包不大(数据包较大,读数据处理复杂度高),如QQ聊天;

channel 类似于流,但流是意向的,通道是双向的

//从文件中读写数据        FileChannel fc = null;        //能通过TCP读写网络中的数据        SocketChannel sc = null;        //能通过UDP读写网络中的数据        DatagramChannel dc = null;        //可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。         ServerSocketChannel ssc = null;

一 通道Channel

Java NIO的通道类似流,但又有些不同: 

    • 既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。
    • 通道可以异步地读写。
    • 通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。

Java NIO中最重要的通道的实现: 

    • FileChannel:从文件中读写数据。
    • DatagramChannel:能通过UDP读写网络中的数据。
    • SocketChannel:能通过TCP读写网络中的数据。
    • ServerSocketChannel:可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。

 

二 组件buffer

缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。 

Java NIO 有以下Buffer类型: 

    • ByteBuffer
    • MappedByteBuffer
    • CharBuffer
    • DoubleBuffer
    • FloatBuffer
    • IntBuffer
    • LongBuffer
    • ShortBuffer

 三 组件selector

Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接。 通常线程越少开销越小,但当前处理器多为多核处理器,多线程任务应该得到充分利用。

一旦向Selector注册了一或多个通道,就可以调用几个重载的select()方法。这些方法返回你所感兴趣的事件(如连接、接受、读或写)已经准备就绪的那些通道。换句话说,如果你对“读就绪”的通道感兴趣,select()方法会返回读事件已经就绪的那些通道。 

下面是select()方法: 

  • int select()
  • int select(long timeout)
  • int selectNow()

select()阻塞到至少有一个通道在你注册的事件上就绪了。 

select(long timeout)和select()一样,除了最长会阻塞timeout毫秒(参数)。 
selectNow()不会阻塞,不管什么通道就绪都立刻返回(译者注:此方法执行非阻塞的选择操作。如果自从前一次选择操作后,没有通道变成可选择的,则此方法直接返回零。)。 
select()方法返回的int值表示有多少通道已经就绪。

selector不会主动向通道发送已就绪事件,需要通过select()方法来获取就绪的通道,根据SelectionKey确定是哪个通道,进行相关的业务处理。

示例代码:

1 Selector selector = Selector.open();   2 channel.configureBlocking(false);   3 SelectionKey key = channel.register(selector, SelectionKey.OP_READ);   4 while(true) {   5   int readyChannels = selector.select();   6   if(readyChannels == 0) continue;   7   Set selectedKeys = selector.selectedKeys();   8   Iterator keyIterator = selectedKeys.iterator();   9   while(keyIterator.hasNext()) {  10     SelectionKey key = keyIterator.next();  11     if(key.isAcceptable()) {  12         // a connection was accepted by a ServerSocketChannel.  13     } else if (key.isConnectable()) {  14         // a connection was established with a remote server.  15     } else if (key.isReadable()) {  16         // a channel is ready for reading  17     } else if (key.isWritable()) {  18         // a channel is ready for writing  19     }  20     keyIterator.remove();  21   }  22 }

 

这个循环遍历已选择键集中的每个键,并检测各个键所对应的通道的就绪事件。

注意每次迭代末尾的keyIterator.remove()调用。Selector不会自己从已选择键集中移除SelectionKey实例。必须在处理完通道时自己移除。下次该通道变成就绪时,Selector会再次将其放入已选择键集中。

四 管道pipe

Java NIO 管道是2个线程之间的单向数据连接(用于线程间数据传递)。Pipe有一个source通道和一个sink通道。数据会被写到sink通道,从source通道读取。

直接上示例代码:

1 package com.lanhuigu.nio.channel; 2   3 import java.io.IOException; 4 import java.nio.ByteBuffer; 5 import java.nio.channels.Pipe; 6   7 public class TestPipe { 8     public static void main(String[] args) throws IOException { 9         // 1. 获取管道10         Pipe pipe = Pipe.open();11  12         // 2. 将缓冲区数据写入到管道13         // 2.1 获取一个通道14         Pipe.SinkChannel sinkChannel = pipe.sink();15         // 2.2 定义缓冲区16         ByteBuffer buffer = ByteBuffer.allocate(48);17         buffer.put("发送数据".getBytes());18         buffer.flip(); // 切换数据模式19         // 2.3 将数据写入到管道20         sinkChannel.write(buffer);21  22         // 3. 从管道读取数据23         Pipe.SourceChannel sourceChannel = pipe.source();24         buffer.flip();25         int len = sourceChannel.read(buffer);26         System.out.println(new String(buffer.array(),0,len));27  28         // 4. 关闭管道29         sinkChannel.close();30         sourceChannel.close();31     }32 }
View Code

 

转载于:https://www.cnblogs.com/lwy329/p/9844554.html

你可能感兴趣的文章
Python复习基础篇
查看>>
关于Cocos2d-x中背景音乐和音效的添加
查看>>
checkbox和文字对齐
查看>>
%s的用法
查看>>
java中==和equals
查看>>
CCActionPageTurn3D
查看>>
python random
查看>>
esp32-智能语音-cli(调试交互命令)
查看>>
netty与MQ使用心得
查看>>
关于dl dt dd 文字过长换行在移动端显示对齐的探讨总结
查看>>
swoolefy PHP的异步、并行、高性能网络通信引擎内置了Http/WebSocket服务器端/客户端...
查看>>
Python学习笔记
查看>>
unshift()与shift()
查看>>
使用 NPOI 、aspose实现execl模板公式计算
查看>>
行为型模式:中介者模式
查看>>
How to Notify Command to evaluate in mvvmlight
查看>>
33. Search in Rotated Sorted Array
查看>>
461. Hamming Distance
查看>>
Python垃圾回收机制详解
查看>>
jquery 编程的最佳实践
查看>>