我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java NIO的基本使用实例

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java NIO的基本使用实例

这篇文章主要介绍“Java NIO的基本使用实例”,在日常操作中,相信很多人在Java NIO的基本使用实例问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java NIO的基本使用实例”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

NIO是Java提供的非阻塞I/O API。

非阻塞的意义在于可以使用一个线程对大量的数据连接进行处理,非常适用于"短数据长连接"的应用场景,例如即时通讯软件。

在一个阻塞C/S系统中,服务器要为每一个客户连接开启一个线程阻塞等待客户端发送的消息.若使用非阻塞技术,服务器可以使用一个线程对连接进行轮询,无须阻塞等待.这大大减少了内存资源的浪费,也避免了服务器在客户线程中不断切换带来的CPU消耗,服务器对CPU的有效使用率大大提高.

其核心概念包括Channel,Selector,SelectionKey,Buffer。

Channel是I/O通道,可以向其注册Selector,应用成功可以通过select操作获取当前通道已经准备好的可以无阻塞执行的操作.这由SelectionKey表示。

SelectionKey的常量字段SelectionKey.OP_***分别对应Channel的几种操作例如connect(),accept(),read(),write()。

select操作后得到SelectionKey.OP_WRITE或者READ即可在Channel上面无阻塞调用read和write方法,Channel的读写操作均需要通过Buffer进行.即读是讲数据从通道中读入Buffer然后做进一步处理.写需要先将数据写入Buffer然后通道接收Buffer。

下面是一个使用NIO的基本C/S示例.该示例只为显示如何使用基本的API而存在,其代码的健壮性,合理性都不具参考价值。

这个示例,实现一个简单的C/S,客户端想服务器端发送消息,服务器将收到的消息打印到控制台.现实的应用中需要定义发送数据使用的协议,以帮助服务器解析消息.本示例只是无差别的使用默认编码将收到的字节转换字符并打印.通过改变初始分配的ByteBuffer的容量,可以看到打印消息的变化.容量越小,对一条消息的处理次数就越多,容量大就可以在更少的循环次数内读完整个消息.所以真是的应用场景,要考虑适当的缓存大小以提高效率。

首先是Server:

package hadix.demo.nio;  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.*; import java.util.concurrent.ConcurrentHashMap;   public class Server {     private Selector selector;     private ByteBuffer readBuffer = ByteBuffer.allocate(8);//调整缓存的大小可以看到打印输出的变化     private Map<SocketChannel, byte[]> clientMessage = new ConcurrentHashMap<>();      public void start() throws IOException {         ServerSocketChannel ssc = ServerSocketChannel.open();         ssc.configureBlocking(false);         ssc.bind(new InetSocketAddress("localhost", 8001));         selector = Selector.open();         ssc.register(selector, SelectionKey.OP_ACCEPT);         while (!Thread.currentThread().isInterrupted()) {             selector.select();             Set<SelectionKey> keys = selector.selectedKeys();             Iterator<SelectionKey> keyIterator = keys.iterator();             while (keyIterator.hasNext()) {                 SelectionKey key = keyIterator.next();                 if (!key.isValid()) {                     continue;                 }                 if (key.isAcceptable()) {                     accept(key);                 } else if (key.isReadable()) {                     read(key);                 }                 keyIterator.remove();             }         }     }      private void read(SelectionKey key) throws IOException {         SocketChannel socketChannel = (SocketChannel) key.channel();          // Clear out our read buffer so it's ready for new data         this.readBuffer.clear();          // Attempt to read off the channel         int numRead;         try {             numRead = socketChannel.read(this.readBuffer);         } catch (IOException e) {             // The remote forcibly closed the connection, cancel             // the selection key and close the channel.             key.cancel();             socketChannel.close();             clientMessage.remove(socketChannel);             return;         }          byte[] bytes = clientMessage.get(socketChannel);         if (bytes == null) {             bytes = new byte[0];         }         if (numRead > 0) {             byte[] newBytes = new byte[bytes.length + numRead];             System.arraycopy(bytes, 0, newBytes, 0, bytes.length);             System.arraycopy(readBuffer.array(), 0, newBytes, bytes.length, numRead);             clientMessage.put(socketChannel, newBytes);             System.out.println(new String(newBytes));         } else {             String message = new String(bytes);             System.out.println(message);         }     }      private void accept(SelectionKey key) throws IOException {         ServerSocketChannel ssc = (ServerSocketChannel) key.channel();         SocketChannel clientChannel = ssc.accept();         clientChannel.configureBlocking(false);         clientChannel.register(selector, SelectionKey.OP_READ);         System.out.println("a new client connected");     }       public static void main(String[] args) throws IOException {         System.out.println("server started...");         new Server().start();     } }

然后是Client:

package hadix.demo.nio;  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; import java.util.Scanner; import java.util.Set;   public class Client {      public void start() throws IOException {         SocketChannel sc = SocketChannel.open();         sc.configureBlocking(false);         sc.connect(new InetSocketAddress("localhost", 8001));         Selector selector = Selector.open();         sc.register(selector, SelectionKey.OP_CONNECT);         Scanner scanner = new Scanner(System.in);         while (true) {             selector.select();             Set<SelectionKey> keys = selector.selectedKeys();             System.out.println("keys=" + keys.size());             Iterator<SelectionKey> keyIterator = keys.iterator();             while (keyIterator.hasNext()) {                 SelectionKey key = keyIterator.next();                 keyIterator.remove();                 if (key.isConnectable()) {                     sc.finishConnect();                     sc.register(selector, SelectionKey.OP_WRITE);                     System.out.println("server connected...");                     break;                 } else if (key.isWritable()) {                      System.out.println("please input message");                     String message = scanner.nextLine();                     ByteBuffer writeBuffer = ByteBuffer.wrap(message.getBytes());                     sc.write(writeBuffer);                 }             }         }     }      public static void main(String[] args) throws IOException {         new Client().start();     } }

此外有一个代码写得更好的例子,非常值得参考。http://rox-xmlrpc.sourceforge.net/niotut/index.html

这个例子里面的客户端将消息发送给服务器,服务器收到后立即写回给客户端.例子中代码虽然也没有做有意义的处理,但是其结构比较合理,值得以此为基础进行现实应用的扩展开发。

到此,关于“Java NIO的基本使用实例”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java NIO的基本使用实例

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java NIO的基本使用实例

这篇文章主要介绍“Java NIO的基本使用实例”,在日常操作中,相信很多人在Java NIO的基本使用实例问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java NIO的基本使用实例”的疑惑有所帮助!接下来
2023-06-17

java NIO SocketClinet和ServerSocket的实例用法

本篇内容介绍了“java NIO SocketClinet和ServerSocket的实例用法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
2023-06-02

Java NIO开发的实例介绍

本篇内容介绍了“Java NIO开发的实例介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!首先来看下传统的阻塞型网络I/O的不足Java
2023-06-17

Java NIO框架Netty简单使用的示例

之前写了一篇文章:Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码),介绍了如何使用Java原生IO支持进行网络编程,本文介绍一种更为简单的方式,即Java NIO框架。Netty是业界最流行的NIO框架之一,具有良好的健
2023-05-30

JavaWeb之Ajax的基本使用与实战案例

ajax技术是使页面能局部刷新的一种技术,下面这篇文章主要给大家介绍了关于JavaWeb之Ajax的基本使用与实战案例的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
2022-11-13

JavaScript中Set基本使用方法实例

因为Set中存放的数据都是不会重复的数据,我们在编写JS代码的时候,因此我们可以利用Set来帮助我们更便捷地完成许多的事,下面这篇文章主要给大家介绍了关于JavaScript中Set基本使用方法的相关资料,需要的朋友可以参考下
2022-11-16

Redis在Java中的基本使用

本片将介绍 Redis 在 Java 中的基本使用 文章目录 1、使用jedis操作redis1.1、Jedis简介1.2、引入jedis的Maven依赖1.2、获取连接1.3、使用实例 2、对于JedisPool
2023-08-21

怎么使用Java NIO实现多人聊天室

本篇内容主要讲解“怎么使用Java NIO实现多人聊天室”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用Java NIO实现多人聊天室”吧!NIO服务端public class NioSe
2023-06-21

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录