zoukankan      html  css  js  c++  java
  • Java中NIO及基础实现

      NIO:同步非壅闭IO
      来源:BIO是同步壅闭IO利用,当线程在处理任务时,另一方会壅闭着等待该线程的履行结束,为了前进效率,,JDK1.4后,引入NIO来提高数据的通讯功能
      NIO中接收Reactor方案形式,注册的汇集点为Selector,NIO有三个紧张构成部门:Channel(通道)、Buffer(缓冲区)、Selector(选择器)
      Reactor方案形式:Reactor形式是一种被动事情处理形式,即当某个特定事情发作时触发事情,可参考,https://blog.csdn.net/feimataxue/article/details/7642638,https://www.cnblogs.com/bitkevin/p/5724410.html
      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;
      publicclassNIOEchoClient{
      publicstaticvoidmain(String[]args)throwsException{
      SocketChannelclientChannel=SocketChannel.open();
      clientChannel.connect(newInetSocketAddress(HostInfo.HOST_NAME,HostInfo.PORT));
      ByteBufferbuffer=ByteBuffer.allocate(50);
      booleanflag=true;
      while(flag){
      buffer.clear();
      Stringinput=InputUtil.getString("请输入待发送的信息:").trim();
      buffer.put(input.getBytes());//将数据存入缓冲区
      buffer.flip();//重置缓冲区
      clientChannel.write(buffer);//发送数据
      buffer.clear();
      intread=clientChannel.read(buffer);
      buffer.flip();
      System.err.print(newString(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;
      publicclassNIOEchoServer{
      privatestaticclassEchoClientHandleimplementsRunnable{
      //客户端
      privateSocketChannelclientChannel;
      //循环竣事标记
      privatebooleanflag=true;
      publicEchoClientHandle(SocketChannelclientChannel){
      this.clientChannel=clientChannel;
      }
      @Override
      publicvoidrun(){
      ByteBufferbyteBuffer=ByteBuffer.allocate(50);
      try{
      while(this.flag){
      byteBuffer.clear();
      intread=this.clientChannel.read(byteBuffer);
      Stringmsg=newString(byteBuffer.array(),0,read).trim();
      StringoutMsg="【Echo】"+msg+" ";//回应信息
      if("byebve".equals(msg)){
      outMsg="会话竣事,下次再见!";
      this.flag=false;


      }
      byteBuffer.clear();
      byteBuffer.put(outMsg.getBytes());//回传信息放入缓冲区
      byteBuffer.flip();
      this.clientChannel.write(byteBuffer);//回传信息
      }
      }catch(Exceptione){
      e.printStackTrace();
      }
      }
      }
      publicstaticvoidmain(String[]args)throwsException{
      //为了功能问题及相应时刻,设置固定巨细的线程池
      ExecutorServiceexecutorService=Executors.newFixedThreadPool(10);
      //NIO根据Channel控制,所以有Selector办理悉数的Channel
      ServerSocketChannelserverSocketChannel=ServerSocketChannel.open();
      //设置为非壅闭形式
      serverSocketChannel.configureBlocking(false);
      //设置监听端口
      serverSocketChannel.bind(newInetSocketAddress(HostInfo.PORT));
      //设置Selector办理悉数Channel
      Selectorselector=Selector.open();
      //注册并设置毗邻时处理
      serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
      System.out.println("服务发动乐成,监听端口为:"+HostInfo.PORT);
      //NIO运用轮询,当有恳求毗邻时,则发动一个线程
      intkeySelect=0;
      while((keySelect=selector.select())>0){
      SetselectionKeys=selector.selectedKeys();
      Iteratoriterator=selectionKeys.iterator();
      while(iterator.hasNext()){
      SelectionKeynext=iterator.next();
      if(next.isAcceptable()){//假如是毗邻的
      SocketChannelaccept=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;
      publicclassInputUtil{
      privatestaticfinalBufferedReaderKEYBOARD_INPUT=newBufferedReader(newInputStreamReader(System.in));
      privateInputUtil(){
      }
      publicstaticStringgetString(Stringprompt){
      booleanflag=true;//数据承受标记
      Stringstr=null;
      while(flag){
      System.out.println(prompt);
      try{
      str=KEYBOARD_INPUT.readLine();//读取一行数据
      if(str==null||"".equals(str)){
      System.out.println("数据输入过错,不允许为空!");
      }else{
      flag=false;
      }
      }catch(IOExceptione){
      e.printStackTrace();
      }
      }
      returnstr;
      }
      }
      packagecom.study.info;
      publiccalssHostInfo{
      publicstaticfinalStringHOST_NAME="localhost";
      publicstaticfinalintPORT=9999;
      }

  • 相关阅读:
    搜索旋转排序数组
    SpringBoot整合mybatis
    《浪潮之巅》阅读笔记01
    阅读杂记01
    go home or stand up
    关于URL编码/javascript/js url 编码(轉)
    水晶报表 相关。
    Format函数(转)
    asp 亂碼問題。
    圣人不死,大盗不止
  • 原文地址:https://www.cnblogs.com/hite/p/12720178.html
Copyright © 2011-2022 走看看