java nio 实现_Java中NIO及基础实现

NIO:同步非阻塞IO

来源:BIO是同步阻塞IO操作,当线程在处理任务时,另一方会阻塞着等待该线程的执行完毕,为了提高效率,,JDK1.4后,引入NIO来提升数据的通讯性能

NIO中采用Reactor设计模式,注册的汇集点为Selector,NIO有三个主要组成部分:Channel(通道)、Buffer(缓冲区)、Selector(选择器)

NIO采用了轮询的方式来观察事件是否执行完毕,如:A让B打印某个文件,BIO会一直等待着B返回,期间自己不做其他事情,而NIO则会不断的询问B是否完成,未完成则处理自己的时,直至B完成

Channel(通道):Channel是一个对象,可以通过它读取和写入数据

Selector(对象选择器): Selector是一个对象,它可以注册到很多个Channel上,监听各个Channel上发生的事件,并且能够根据事件情况决定Channel读写

代码实现:(此实现参考网络上可用的例子)

NIO客户端实现:

packagecom.learn.nio.client;importcom.study.info.HostInfo;importcom.study.util.InputUtil;importjava.net.InetSocketAddress;importjava.nio.ByteBuffer;importjava.nio.channels.SocketChannel;public classNIOEchoClient {public static void main(String[] args) throwsException{

SocketChannel clientChannel=SocketChannel.open();

clientChannel.connect(newInetSocketAddress(HostInfo.HOST_NAME,HostInfo.PORT));

ByteBuffer buffer= ByteBuffer.allocate(50);boolean flag = true;while(flag){

buffer.clear();

String input= InputUtil.getString("请输入待发送的信息:").trim();

buffer.put(input.getBytes());//将数据存入缓冲区

buffer.flip(); //重置缓冲区

clientChannel.write(buffer); //发送数据

buffer.clear();int read =clientChannel.read(buffer);

buffer.flip();

System.err.print(new String(buffer.array(), 0, read));if("byebye".equalsIgnoreCase(input)){

flag= false;

}

}

clientChannel.close();

}

}

NIO服务端实现:

packagecom.learn.nio.server;importcom.study.info.HostInfo;importjava.net.InetSocketAddress;importjava.nio.ByteBuffer;importjava.nio.channels.SelectionKey;importjava.nio.channels.Selector;importjava.nio.channels.ServerSocketChannel;importjava.nio.channels.SocketChannel;importjava.util.Iterator;importjava.util.Set;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;public classNIOEchoServer {private static class EchoClientHandle implementsRunnable {//客户端

privateSocketChannel clientChannel;//循环结束标记

private boolean flag = true;publicEchoClientHandle(SocketChannel clientChannel){this.clientChannel =clientChannel;

}

@Overridepublic voidrun() {

ByteBuffer byteBuffer= ByteBuffer.allocate(50);try{while (this.flag){

byteBuffer.clear();int read = this.clientChannel.read(byteBuffer);

String msg= new String(byteBuffer.array(), 0, read).trim();

String outMsg= "【Echo】" + msg + "\n"; //回应信息

if("byebve".equals(msg)){

outMsg= "会话结束,下次再见!";this.flag = false;

}

byteBuffer.clear();

byteBuffer.put(outMsg.getBytes());//回传信息放入缓冲区

byteBuffer.flip();this.clientChannel.write(byteBuffer);//回传信息

}

}catch(Exception e){

e.printStackTrace();

}

}

}public static void main(String[] args) throwsException{//为了性能问题及响应时间,设置固定大小的线程池

ExecutorService executorService = Executors.newFixedThreadPool(10);//NIO基于Channel控制,所以有Selector管理所有的Channel

ServerSocketChannel serverSocketChannel =ServerSocketChannel.open();//设置为非阻塞模式

serverSocketChannel.configureBlocking(false);//设置监听端口

serverSocketChannel.bind(newInetSocketAddress(HostInfo.PORT));//设置Selector管理所有Channel

Selector selector =Selector.open();//注册并设置连接时处理

serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

System.out.println("服务启动成功,监听端口为:" +HostInfo.PORT);//NIO使用轮询,当有请求连接时,则启动一个线程

int keySelect = 0;while ((keySelect = selector.select()) > 0){

Set selectionKeys =selector.selectedKeys();

Iterator iterator =selectionKeys.iterator();while(iterator.hasNext()){

SelectionKey next=iterator.next();if(next.isAcceptable()){ //如果是连接的

SocketChannel accept =serverSocketChannel.accept();if(accept != null){

executorService.submit(newEchoClientHandle(accept));

}

iterator.remove();

}

}

}

executorService.shutdown();

serverSocketChannel.close();

}

}

工具类:

packagecom.study.util;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;public classInputUtil {private static final BufferedReader KEYBOARD_INPUT = new BufferedReader(newInputStreamReader(System.in));privateInputUtil(){

}public staticString getString(String prompt){boolean flag = true; //数据接受标记

String str = null;while(flag){

System.out.println(prompt);try{

str= KEYBOARD_INPUT.readLine(); //读取一行数据

if(str == null || "".equals(str)){

System.out.println("数据输入错误,不允许为空!");

}else{

flag= false;

}

}catch(IOException e) {

e.printStackTrace();

}

}returnstr;

}

}

packagecom.study.info;publiccalss HostInfo {public static final String HOST_NAME = "localhost";public static final int PORT = 9999;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值