一,先说java IO

1,线程阻塞:当线程调用write()read()时,线程会被阻塞,直到有一些数据可用于读取或数据被完全写入。

2,面向流: 我们需要从流中读取一个或多个字节。它使用流来在数据源/槽和java程序之间传输数据。从源进入 Java对象成为“input” , 从Java 对象 写出称为“ouput” .

二,同步非阻塞IO:当内核数据没有准备好的情况下,并不会一直阻塞等待,而是立即返回。随后多次发起系统调用,轮询过程。

优点: 不会等待阻塞,失败立即返回。

缺点: 多次发起调用,轮询过程消耗资源。

三,多路复用IO:select/epoll系统调用,单个线程不断的轮询select/epoll系统调用所负责的成百上千的socket连接,当某个或者某些socket网络连接有数据到达了,就返回这些可           以读写的连接。 在 Linux 下,实现高并发网络编程时都是以 IO 复用模型模式为主。这是同步非阻塞的升级。

优点:之前是一个线程对应一个连接。现在是一个线程对应多个连接。  适合高并发场景;系统不必创建线程,也不必维护这些线程,从而大大减小了系统的开销。

缺点:需要不断的进行select/epoll轮询,查找出可以进行IO操作的连接;select/epoll系统调用,属于同步IO,也是阻塞IO。也就是说这个读写过程是阻塞的。

二,java NIO 原理

就是多路复用原理。

三 , NIO 简单例子

package org.example;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set; public class NIOServer { public static void main(String[] args) throws IOException { Selector selector = Selector.open(); // 开启选择器
ServerSocketChannel SocketChannel = ServerSocketChannel.open();
InetSocketAddress addr = new InetSocketAddress("localhost", 1111);
SocketChannel.bind(addr); //服务器端建立channel ,绑定到端口
SocketChannel.configureBlocking(false); // 配置channel阻塞模式
int ops = SocketChannel.validOps();
SelectionKey selectKy = SocketChannel.register(selector, ops, null);
// 无限循环,保持服务器运行
while (true) {
log("我是服务器,我在等待连接... ");
selector.select(); // 从很多key中选择 已IO准备好的channel
Set<SelectionKey> Keys = selector.selectedKeys(); //从选择器中选择“已准备好的通道(对应的key)”
Iterator<SelectionKey> Iterator = Keys.iterator();
while (Iterator.hasNext()) {
SelectionKey myKey = Iterator.next();
//测试通道是否可以接收socket 连接
if (myKey.isAcceptable()) {
SocketChannel socketChannel = SocketChannel.accept();
// 修改通道阻塞模式
socketChannel.configureBlocking(false);
// 为读操作进行配置
socketChannel.register(selector, SelectionKey.OP_READ);
log("成功连接到: " + socketChannel.getLocalAddress() + "\n");
// 测试通道是否可以读
} else if (myKey.isReadable()) {
SocketChannel socketChannel = (SocketChannel) myKey.channel();
ByteBuffer Buffer = ByteBuffer.allocate(256);
socketChannel.read(Buffer);
String result = new String(Buffer.array()).trim();
log("接收到消息: " + result);
if (result.equals(".com")) {
socketChannel.close();
log("\n接收到最后一个companie name,可以关闭连接 ''");
log("\n服务器保持运行,可以继续重启客户端建立新连接进行测试。 ");
}
}
Iterator.remove();
}
}
} private static void log(String str) {
System.out.println(str);
}
} public class NIOClient {
public static void main(String[] args) throws IOException, InterruptedException { InetSocketAddress addr = new InetSocketAddress("localhost", 1111); // 建立数据报通道,并绑定地址
SocketChannel socketChannel = SocketChannel.open(addr); //channel 绑定到端口。 log("连接到服务器,端口1111...");
ArrayList<String> companyDetails = new ArrayList<String>(); //构造传输的数据 companyDetails.add("Facebook");
companyDetails.add("Twitter");
companyDetails.add("IBM");
companyDetails.add("Google");
companyDetails.add("alibaba.com");
companyDetails.add(".com"); for (String companyName : companyDetails) {
byte[] message = new String(companyName).getBytes();
ByteBuffer buffer = ByteBuffer.wrap(message); // 功能:定位 ,容量,
socketChannel.write(buffer); //将Buffer中的数据读入通道
log("发送消息: " + companyName);
buffer.clear();
Thread.sleep(2000);
}
socketChannel.close();
} private static void log(String str) {
System.out.println(str);
}
}

运行结果:

java NIO原理和代码实践的更多相关文章

  1. [JavaEE]Java NIO原理图文分析及代码实现

    转http://weixiaolu.iteye.com/blog/1479656 目录: 一.java NIO 和阻塞I/O的区别      1. 阻塞I/O通信模型      2. java NIO ...

  2. Java NIO原理图文分析及代码实现

    原文: http://weixiaolu.iteye.com/blog/1479656 目录: 一.java NIO 和阻塞I/O的区别      1. 阻塞I/O通信模型      2. java ...

  3. Java NIO原理 图文分析及代码实现

    Java NIO原理图文分析及代码实现 前言:  最近在分析hadoop的RPC(Remote Procedure Call Protocol ,远程过程调用协议,它是一种通过网络从远程计算机程序上请 ...

  4. Java NIO原理分析

    Java IO 在Client/Server模型中,Server往往需要同时处理大量来自Client的访问请求,因此Server端需采用支持高并发访问的架构.一种简单而又直接的解决方案是“one-th ...

  5. Java NIO原理和使用

    Java NIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打开一个I/O通道后,read()将一直等待在端口一边读取字节内 ...

  6. Java NIO原理和使用(转载一)

    Java NIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打开一个I/O通道后,read()将一直等待在端口一边读取字节内 ...

  7. Java NIO原理及实例

    Java NIO是在jdk1.4开始使用的,它既可以说成“新I/O”,也可以说成非阻塞式I/O.下面是java NIO的工作原理: 1. 由一个专门的线程来处理所有的 IO 事件,并负责分发. 2. ...

  8. java NIO 原理解析之学习笔记

    关键抽象 1.Buffer缓冲区 NIO数据传递模型,是一个连续的内存区域.所有数据传递均通过buffer类处理:NIO提供了字符串.整形.字节.堆等多种缓冲区. 2.Channel(通道) NIO把 ...

  9. 10分钟看懂, Java NIO 底层原理

    目录 写在前面 1.1. Java IO读写原理 1.1.1. 内核缓冲与进程缓冲区 1.1.2. java IO读写的底层流程 1.2. 四种主要的IO模型 1.3. 同步阻塞IO(Blocking ...

  10. java NIO系列教程1

    ava NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式. Java NIO: Channel ...

随机推荐

  1. 学习Java Day28

    今天简单的学习了一下文档的注释,注释插入以/**开始,以*/结束,每个/**...*/文档注释包含标记以及之后紧跟着的自由格式文本 然后类注释必须放在import语句之后,类定义之前: 方式注释必须放 ...

  2. B端业务中仓库标签打印系统设计方案

    需求背景: 仓库在给客户货物打包途中需要在包裹上贴标签,在客户比较多且标签样式多样化的前提下,给仓库人员带来了工作量,为了节约仓库人员工作流程时间,公司开发了一套标签管理系统: 前提条件:选择专属打印 ...

  3. 调式源码解决 seata 报错 can not get cluster name 问题

    最近在使用Spring Cloud整合分布式事务seata,项目启动之后,控制台一直报错: can not get cluster name in registry config 'service.v ...

  4. [EULAR文摘] 新证据: NSAID对AS放射学进展的影响

    新证据: NSAID对AS放射学进展的影响 Sieper J, et al. EULAR 2015. Present ID: OP0145. 背景: 既往有研究显示持续给予NSAID相较于按需给药能在 ...

  5. 代码随想录算法训练营day21 | leetcode ● 530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ● ***236. 二叉树的最近公共祖先

    LeetCode 530.二叉搜索树的最小绝对差 分析1.0 二叉搜索树,中序遍历形成一个升序数组,节点差最小值一定在中序遍历两个相邻节点产生 ✡✡✡ 即 双指针思想在树遍历中的应用 class So ...

  6. LeetCode算法训练-动态规划

    欢迎关注个人公众号:爱喝可可牛奶 LeetCode算法训练-动态规划 理论知识 动态规划当前状态是由前一个状态推导出来的,而贪心没有状态的转移 动态规划需要借助dp数组,可能是一维也可能是二维的 首先 ...

  7. XView 架构升级之路

    作者:京东零售 胡本奎 一 背景 1 是什么 XView是一个透明的塑料袋(容器),基于通用的webview框架改造而来,通常用于大促弹窗等营销场景,展现形式如下图: 2 痛点 在实际的开发使用中XV ...

  8. (三) Mysql 之MVCC

    mvcc介绍 MVCC是数据库提供并发访问控制的一种技术.其核心理念是数据快照,不同的事务访问不同版本的数据快照,从而实现不同的事务隔离级别.虽然是说具有多个版本的数据快照,但这并不意味着数据库必须拷 ...

  9. 副三角形行列式转成上(下)三角形行列式为什么依次对换而不用第n行直接对换首行,第n-1行直接对换次行

    副三角形行列式转成上(下)三角形行列式为什么依次对换而不用第n行直接对换首行,第n-1行直接对换次行 前言:重在记录,可能出错. 1. 简而言之,可以用第n行直接对换首行,第n-1行直接对换次行,直到 ...

  10. C#窗体控件,文字随电脑分辨率自动调整大小

    一.在类中添加方法,代码如下: #region 窗体控件.字体随分辨率调整,自动调整大小 public static void SetTag(Control cons) { foreach (Cont ...