加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

架构师知识储备——深入理解BIO、NIO、AIO

发布时间:2019-10-18 17:18:54 所属栏目:建站 来源:咔咔侃技术
导读:本文你将获取到:同/异步 + 阻/非阻塞的性能区别;BIO、NIO、AIO 的区别;理解和实现 NIO 操作 Socket 时的多路复用;同时掌握 IO 最底层最核心的操作技巧。 BIO、NIO、AIO 的区别是什么? 同/异步、阻/非阻塞的区别是什么? 文件读写最优雅的实现方式是什么? N

阻塞与非阻塞主要是从 CPU 的消耗上来说的,阻塞就是 CPU 停下来等待一个慢的操作完成 CPU 才接着完成其它的事。非阻塞就是在这个慢的操作在执行时 CPU 去干其它别的事,等这个慢的操作完成时,CPU 再接着完成后续的操作。虽然表面上看非阻塞的方式可以明显的提高 CPU 的利用率,但是也带了另外一种后果就是系统的线程切换增加。增加的 CPU 使用时间能不能补偿系统的切换成本需要好好评估。

2.3 同/异、阻/非堵塞 组合

同/异、阻/非堵塞的组合,有四种类型,如下表:

架构师知识储备——深入理解BIO、NIO、AIO

三、优雅的文件读写

Java 7 之前文件的读取是这样的:

  1. // 添加文件 
  2. FileWriter fileWriter = new FileWriter(filePath, true); 
  3. fileWriter.write(Content); 
  4. fileWriter.close(); 
  5. // 读取文件 
  6. FileReader fileReader = new FileReader(filePath); 
  7. BufferedReader bufferedReader = new BufferedReader(fileReader); 
  8. StringBuffer bf = new StringBuffer(); 
  9. String str; 
  10. while ((str = bufferedReader.readLine()) != null) { 
  11.  bf.append(str + "n"); 
  12. bufferedReader.close(); 
  13. fileReader.close(); 
  14. System.out.println(bf.toString()); 

Java 7 引入了Files(java.nio包下)的,大大简化了文件的读写,如下:

  1. // 写入文件(追加方式:StandardOpenOption.APPEND) 
  2. Files.write(Paths.get(filePath), Content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND); 
  3. // 读取文件 
  4. byte[] data = Files.readAllBytes(Paths.get(filePath)); 
  5. System.out.println(new String(data, StandardCharsets.UTF_8)); 

读写文件都是一行代码搞定,没错这就是最优雅的文件操作。

Files 下还有很多有用的方法,比如创建多层文件夹,写法上也简单了:

  1. // 创建多(单)层目录(如果不存在创建,存在不会报错) 
  2. new File("D://a//b").mkdirs(); 

四、Socket 和 NIO 的多路复用

本节带你实现最基础的 Socket 的同时,同时会实现 NIO 多路复用,还有 AIO 中 Socket 的实现。

4.1 传统的 Socket 实现

接下来我们将会实现一个简单的 Socket,服务器端只发给客户端信息,再由客户端打印出来的例子,代码如下:

  1. int port = 4343; //端口号 
  2. // Socket 服务器端(简单的发送信息) 
  3. Thread sThread = new Thread(new Runnable() { 
  4.  @Override 
  5.  public void run() { 
  6.  try { 
  7.  ServerSocket serverSocket = new ServerSocket(port); 
  8.  while (true) { 
  9.  // 等待连接 
  10.  Socket socket = serverSocket.accept(); 
  11.  Thread sHandlerThread = new Thread(new Runnable() { 
  12.  @Override 
  13.  public void run() { 
  14.  try (PrintWriter printWriter = new PrintWriter(socket.getOutputStream())) { 
  15.  printWriter.println("hello world!"); 
  16.  printWriter.flush(); 
  17.  } catch (IOException e) { 
  18.  e.printStackTrace(); 
  19.  } 
  20.  } 
  21.  }); 
  22.  sHandlerThread.start(); 
  23.  } 
  24.  } catch (IOException e) { 
  25.  e.printStackTrace(); 
  26.  } 
  27.  } 
  28. }); 
  29. sThread.start(); 
  30. // Socket 客户端(接收信息并打印) 
  31. try (Socket cSocket = new Socket(InetAddress.getLocalHost(), port)) { 
  32.  BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(cSocket.getInputStream())); 
  33.  bufferedReader.lines().forEach(s -> System.out.println("客户端:" + s)); 
  34. } catch (UnknownHostException e) { 
  35.  e.printStackTrace(); 
  36. } catch (IOException e) { 
  37.  e.printStackTrace(); 
  • 调用 accept 方法,阻塞等待客户端连接;
  • 利用 Socket 模拟了一个简单的客户端,只进行连接、读取和打印;

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读