Java NIO工作原理
数据通信流程:
通过selector.select()阻塞方法获取到感兴趣事件的key,根据key定位到channel,通过channel的读写操作进行数据通信。channel的read或者write操作都是通过buffer进行的。
代码示例
Server:
public class Server {
public static void main(String[] args) throws InterruptedException {
final int port = 9999;
try {
// 初始化server
ServerSocketChannel server = ServerSocketChannel.open();
server.socket().bind(new InetSocketAddress(port));
Selector selector = Selector.open();
// 这一步的设置在register中需要用到,所以要在register之前设置,否则会发生异常
server.configureBlocking(false);
SelectionKey serverKey = server.register(selector, SelectionKey.OP_ACCEPT);
ByteBuffer buffer = ByteBuffer.allocate(50);
// 事件循环
while(true) {
Thread.sleep(500);
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iterator = keys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
if (!key.isValid()) {
continue;
}
if (key.isAcceptable()) {
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel sc = ssc.accept();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
// System.out.println(serverKey == key);
continue;
}
if (key.isReadable()) {
SocketChannel sc = (SocketChannel) key.channel();
sc.read(buffer);
buffer.flip();
System.out.println(new String(buffer.array(), 0, buffer.limit()));
}
if (key.isWritable()) {
SocketChannel sc = (SocketChannel) key.channel();
sc.write(ByteBuffer.wrap("I am server!".getBytes()));
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client:
public class Client {
public static void main(String[] args) throws IOException, InterruptedException {
SocketChannel client = SocketChannel.open();
client.connect(new InetSocketAddress("localhost", 9999));
client.configureBlocking(false);
ByteBuffer buffer = ByteBuffer.allocate(50);
while (true) {
buffer.clear();
int i = client.read(buffer);
if (i > 0) {
buffer.flip();
System.out.println(new String(buffer.array(), 0, buffer.limit()));
}
client.write(ByteBuffer.wrap("I am a client!".getBytes()));
Thread.sleep(500);
}
}
}
其他
运行在Linux kernel 2.6以后的OS中的Java应用,NIO的底层实现是根据OS提供的io多路复用接口epoll实现。
参考资料
- 论文《Scalable IO in Java》:http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf (强烈推荐,NIO的源头)
- NIO基础教程:http://ifeve.com/java-nio-all
- C语言下的epoll使用:https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/
Java NIO工作原理的更多相关文章
- 全面解读Java NIO工作原理(4)
全面解读Java NIO工作原理(4) 2011-12-14 10:31 Rollen Holt Rollen Holt的博客 我要评论(0) 字号:T | T JDK 1.4 中引入的新输入输出 ( ...
- 全面解读Java NIO工作原理(3)
全面解读Java NIO工作原理(3) 2011-12-14 10:31 Rollen Holt Rollen Holt的博客 我要评论(0) 字号:T | T JDK 1.4 中引入的新输入输出 ( ...
- 全面解读Java NIO工作原理(2)
全面解读Java NIO工作原理(2) 2011-12-14 10:31 Rollen Holt Rollen Holt的博客 我要评论(0) 字号:T | T JDK 1.4 中引入的新输入输出 ( ...
- 全面解读Java NIO工作原理(1)
全面解读Java NIO工作原理(1) 2011-12-14 10:31 Rollen Holt Rollen Holt的博客 我要评论(0) 字号:T | T JDK 1.4 中引入的新输入输出 ( ...
- JAVA NIO工作原理及代码示例
简介:本文主要介绍了JAVA NIO中的Buffer, Channel, Selector的工作原理以及使用它们的若干注意事项,最后是利用它们实现服务器和客户端通信的代码实例. 欢迎探讨,如有错误敬请 ...
- (前篇:NIO系列 推荐阅读) Java NIO 底层原理
出处: Java NIO 底层原理 目录 1.1. Java IO读写原理 1.1.1. 内核缓冲与进程缓冲区 1.1.2. java IO读写的底层流程 1.2. 四种主要的IO模型 1.3. 同步 ...
- Java虚拟机工作原理详解 (一)
一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了解java程序工作原理.首先,你写好java代码,保存到硬盘当中.然后你在命令行中输入 javac YourClassNam ...
- Java虚拟机工作原理详解
原文地址:http://blog.csdn.net/bingduanlbd/article/details/8363734 一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了 ...
- Java虚拟机工作原理具体解释
一.类载入器 首先来看一下java程序的运行过程. 从这个框图非常easy大体上了解java程序工作原理.首先,你写好java代码,保存到硬盘其中.然后你在命令行中输入 javac YourClass ...
随机推荐
- Vijos1881闪烁的繁星 [线段树]
P1881闪烁的繁星 背景 繁星闪烁着--深蓝的太空何曾听得见他们对语沉默中微光里他们深深的互相颂赞了 描述 繁星, 漫天的繁星.繁星排成一列, 我数一数呀, 一共有N只小星星呢. 星星们是听话的好 ...
- mysql 性能优化方案
网 上有不少MySQL 性能优化方案,不过,mysql的优化同sql server相比,更为麻烦与复杂,同样的设置,在不同的环境下 ,由于内存,访问量,读写频率,数据差异等等情况,可能会出现不同的结果 ...
- .net Global.asax文件使用
一.Application_start: 第一个访问网站的用户会触发该方法. 通常会在该方法里定义一些系统变量,如聊天室的在线总人数统计,历史访问人数统计的初始化等等均可在这里定义. Applicat ...
- Golang友团无闻Go语言Web基础视频教程
教程内容:GO语言资料Golang友团无闻Go语言编程基础Golang友团无闻Go语言Web基础教程 Go语言Web基础教程列表:[Go Web基础]12Go Web 扩展学习.mp4[Go Web基 ...
- JavaScript从数组中删除指定值元素的方法
本文实例讲述了JavaScript从数组中删除指定值元素的方法.分享给大家供大家参考.具体分析如下: 下面的代码使用了两种方式删除数组的元素,第一种定义一个单独的函数,第二种为Array对象定义了一个 ...
- a href=#与 a href=javascript:void(0) 的区别
a href="#"> 点击链接后,页面会向上滚到页首,# 默认锚点为 #TOP <a href="javascript:void(0)" onCl ...
- 种子填充算法描述及C++代码实现
项目需要看了种子填充算法,改进了算法主要去除面积小的部分.种子填充算法分为两种,简单的和基于扫描线的方法,简单的算法如下描述(笔者针对的是二值图像): (1)从上到下,从左到有,依次扫描每个像素: ( ...
- myeclipse 注释模板
选中你要加注释的方法或类,按 Alt + shift + J.
- mysql select
select 查询: 赋值:赋值不能应用在where中,因为where操作的是磁盘上的文件,可以应用在having筛选中. 例:select (market_price-shop_price) as ...
- BZOJ 3236: [Ahoi2013]作业
3236: [Ahoi2013]作业 Time Limit: 100 Sec Memory Limit: 512 MBSubmit: 1393 Solved: 562[Submit][Status ...