管道流:

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

 package base.nio.threaddemo;

 import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Pipe; /**
* @program: Lear-Java
* @description:
* @author: Mr.Dai
* @create: 2018-10-05 20:43
**/
public class ThreadSend { private Pipe pipe; private void init() throws Exception {
this.pipe = Pipe.open();
} class SendInner1 extends Thread { @Override
public void run() {
// 单向流 发送数据
try {
Pipe.SinkChannel sink = pipe.sink();
sink.configureBlocking(false); while (true) {
if (sink.isOpen()) {
sink.write(ByteBuffer.wrap("abcd".getBytes()));
}
Thread.sleep(1000);
}
} catch (InterruptedException | IOException e) {
e.printStackTrace();
}
}
} class ReverInner extends Thread {
@Override
public void run() {
try {
// 单向流 拿到数据
Pipe.SourceChannel source = pipe.source(); source.configureBlocking(false); while (true) {
if (source.isOpen()) {
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.clear();
source.read(buffer);
// 这里必须去掉 trim
if(new String(buffer.array()).trim().equals("")){
continue;
}
System.out.println(new String(buffer.array()).trim());
}
Thread.sleep(1000);
}
} catch (InterruptedException | IOException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) throws Exception {
ThreadSend send = new ThreadSend(); send.init(); SendInner1 sendI = send.new SendInner1(); ReverInner revI = send.new ReverInner(); sendI.start();
revI.start();
} }

套接字通道流

非阻塞模式

ServerSocketChannel可以设置成非阻塞模式。在非阻塞模式下,accept() 方法会立刻返回,如果还没有新进来的连接,返回的将是null。 因此,需要检查返回的SocketChannel是否是null。如:

 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();  

 serverSocketChannel.socket().bind(new InetSocketAddress(9999));
serverSocketChannel.configureBlocking(false); 6 while(true){
SocketChannel socketChannel =
serverSocketChannel.accept(); if(socketChannel != null){
//do something with socketChannel...
}
}

server:

 package base.nio.chatdemo;

 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; /**
* @program: Lear-Java
* @description: Nio 聊天服务端
* @author: Mr.Dai
* @create: 2018-10-05 16:31
**/
public class ChatServer { /**
* 通道管理器
*/
private Selector selector; private void initServer(int port) throws Exception{ ServerSocketChannel serverChannel = ServerSocketChannel.open(); serverChannel .socket().bind(new InetSocketAddress(port));
// 配置非阻塞
serverChannel .configureBlocking(false); this.selector=Selector.open(); /**
* 将通道管理器和该通道绑定,并为该通道注册selectionKey.OP_ACCEPT事件
* 注册该事件后,当事件到达的时候,selector.select()会返回,
* 如果事件没有到达selector.select()会一直阻塞
* selector.selectNow() 立即返回 无论是否准备好 可能返回0
*/
serverChannel .register(this.selector, SelectionKey.OP_ACCEPT); } /**
* 采用轮训的方式监听selector上是否有需要处理的事件,如果有,进行处理
*/
public void listen() throws Exception {
System.out.println("start------------------->");
while (true){
// 在没有注册事件来到时 将会一直阻塞
selector.select();
Set<SelectionKey> set = selector.selectedKeys();
Iterator<SelectionKey> iterator = set.iterator(); while (iterator.hasNext()){
SelectionKey key = iterator.next();
// 移除当前阻塞队列
iterator.remove();
if(key.isAcceptable()){
ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel channel = server.accept();
channel.configureBlocking(false);
// 服务端发送数据
channel.write(ByteBuffer.wrap(new String("hello client").getBytes()));
// 在客户端连接成功之后,为了可以接收到客户端的信息,需要给通道设置读的权限
channel.register(this.selector,SelectionKey.OP_READ); }else if(key.isReadable()){
SocketChannel channel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(10);
channel.read(buffer); String msg = new String(buffer.array()).trim(); System.out.println("客户端发送过来的讯息:"+msg);
// 在读取后 将柱塞队列数据 改变监听为Accept
ByteBuffer outBuffer = ByteBuffer.wrap(msg.getBytes());
channel.write(outBuffer);
}
}
} } public static void main(String[] args) throws Exception{
ChatServer server = new ChatServer();
server.initServer(8989);
server.listen();
} }

clien:

 package base.nio.chatdemo;

 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.SocketChannel;
import java.util.Iterator; /**
* @program: Lear-Java
* @description: nio 聊天客户端
* @author: Mr.Dai
* @create: 2018-10-05 16:31
**/
public class ChatClient { /**
* 提供柱阻塞队列 管理器
*/
private Selector selector; private void ininCliect(String ip,int port) throws Exception{ SocketChannel channel = SocketChannel.open(); channel .connect(new InetSocketAddress(ip,port)); this.selector=Selector.open(); channel .configureBlocking(false); channel .register(this.selector, SelectionKey.OP_CONNECT); } public void listen() throws Exception { while (true){ selector.select(); Iterator<SelectionKey> ite = selector.selectedKeys().iterator(); while (ite.hasNext()){
SelectionKey key = ite .next();
ite .remove();
if(key.isConnectable()){
SocketChannel channel = (SocketChannel) key.channel();
// 是否准备好连接
if(channel.isConnectionPending()){
channel.finishConnect();
}
channel.configureBlocking(false);
// 向server 发送数据
channel.write(ByteBuffer.wrap("向server 发送数据".getBytes())); channel.register(selector,SelectionKey.OP_READ); }else if(key.isReadable()){
m1(key);
}
}
}
} private void m1(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(10);
channel.read(buffer);
System.out.println("服务端的消息为:"+new String(buffer.array())); ByteBuffer outBuffer = ByteBuffer.wrap(new String("aaa").getBytes());
channel.write(outBuffer);
} public static void main(String[] args) throws Exception {
ChatClient client = new ChatClient(); client.ininCliect("127.0.0.1",8989);
client.listen();
} }

Java NIO 必知必会(Example)的更多相关文章

  1. 必知必会之 Java

    必知必会之 Java 目录 不定期更新中-- 基础知识 数据计量单位 面向对象三大特性 基础数据类型 注释格式 访问修饰符 运算符 算数运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 三目表达式 ...

  2. Java面试必知必会:基础

    面试考察的知识点多而杂,要完全掌握需要花费大量的时间和精力.但是面试中经常被问到的知识点却没有多少,你完全可以用 20% 的时间去掌握 80% 常问的知识点. 一.基础 包括: 杂七杂八 面向对象 数 ...

  3. 第5节:Java基础 - 必知必会(下)

    第5节:Java基础 - 必知必会(下) 本小节是Java基础篇章的第三小节,主要讲述Java中的Exception与Error,JIT编译器以及值传递与引用传递的知识点. 一.Java中的Excep ...

  4. 第4节:Java基础 - 必知必会(中)

    第4节:Java基础 - 必知必会(中) 本小节是Java基础篇章的第二小节,主要讲述抽象类与接口的区别,注解以及反射等知识点. 一.抽象类和接口有什么区别 抽象类和接口的主要区别可以总结如下: 抽象 ...

  5. 第3节:Java基础 - 必知必会(上)

    第3节:Java基础 - 必知必会(上) 本篇是基础篇的第一小节,我们从最基础的java知识点开始学习.本节涉及的知识点包括面向对象的三大特征:封装,继承和多态,并且对常见且容易混淆的重要概念覆盖和重 ...

  6. Java并发必知必会第三弹:用积木讲解ABA原理

    Java并发必知必会第三弹:用积木讲解ABA原理 可落地的 Spring Cloud项目:PassJava 本篇主要内容如下 一.背景 上一节我们讲了程序员深夜惨遭老婆鄙视,原因竟是CAS原理太简单? ...

  7. 必知必会之Java注解

    必知必会之Java注解 目录 不定期更新中-- 元注解 @Documented @Indexed @Retention @Target 常用注解 @Deprecated @FunctionalInte ...

  8. Java面试必知必会(扩展)——Java基础

    float f=3.4;是否正确? 不正确 3.4是双精度,将双精度赋值给浮点型属于向下转型,会造成精度损失: 因此需要强制类型转换: 方式一:float f=(float)3.4 方式二:float ...

  9. mysql必知必会系列(一)

    mysql必知必会系列是本人在读<mysql必知必会>中的笔记,方便自己以后查看. MySQL. Oracle以及Microsoft SQL Server等数据库是基于客户机-服务器的数据 ...

  10. 《MySQL必知必会》整理

    目录 第1章 了解数据库 1.1 数据库基础 1.1.1 什么是数据库 1.1.2 表 1.1.3 列和数据类型 1.1.4 行 1.1.5 主键 1.2 什么是SQL 第2章 MySQL简介 2.1 ...

随机推荐

  1. oracle删除重复数据只保留一条

    -- 如表role_user的数据 ROLEID USERID -- 删除相同记录只剩下一条记录 根据两个字段查询重复数据 (roleid,userid) ) 删除重复数据只保留一条 delete f ...

  2. VLAN虚拟局域网技术(二)-计算机网络

    本文主要知识来源于学校课程,部分知识来自于H3C及思科中国公司网页技术手册,未经许可,禁止转载.如需转载,请联系作者并注明出处. 本节主要是总结一些思科的VLAN组中的私有协议:DTP和VTP. 1. ...

  3. gVim/Vim 一键编译、连接、运行 C/C++ 单文件

    用于Gvim 或 Vim 配置文件的一键编译与运行函数(注:需要机器上安装了GCC才行) 本代码只加入了对C/C++的编译与运行,如果要加入其语言的可以参考此代码加入即可 同时,本代码加入了对Wind ...

  4. 「洛谷 P1801」黑匣子

    好像很久没有更过博客了,因为博主这几周很忙.其实是在搞颓. 题意很难懂,所以就不重复了.其实是懒. 一眼看上去这是个 \(Splay\) 裸题,直接插入一个数,查询区间第 \(K\) 大,但是这样太不 ...

  5. linux标准输入输出与重定向

    原文:http://blog.sina.com.cn/s/blog_8333cf8f0100vzzl.html##1 1. 标准输入输出和错误    linux下使用标准输入文件stdin和标准输出文 ...

  6. oracle Instant Client install

    Installation See the Instant Client Home Page for more information. Installation of ZIP files: 1. Do ...

  7. 1034 Head of a Gang (30)(30 分)

    One way that the police finds the head of a gang is to check people's phone calls. If there is a pho ...

  8. codevs 1144 守望者的逃离

    传送门 1144 守望者的逃离 2007年NOIP全国联赛普及组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解   题目描述 Description 恶 ...

  9. Btree算法的C语言实现

    btree.h //实现对order序(阶)的B-TREE结构基本操作的封装. //查找:search,插入:insert,删除:remove. //创建:create,销毁:destory,打印:p ...

  10. bzoj 4883 [Lydsy1705月赛]棋盘上的守卫——并查集(思路!)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4883 把各行和各列看成n+m个点. 如果一下能防守行和列,就是最大匹配了.这是每两个左右部点 ...