zoukankan      html  css  js  c++  java
  • Java IO编程中的几个概念

    BIO NIO AIO

    java中的BIO NIO AIO 是在不同java版本更新过程中依次引入的, 性能也越来越好.
    这个3个IO分别指:

    • BIO:同步阻塞IO, 传统的java.io包.
    • NIO: new IO, 是一种同步非阻塞IO, java,nio包, java 1.4引入.
    • AIO: 异步非阻塞IO, 也称NIO2, 由java 1.7引入, 应用还不是特别广泛.

    阻塞 非阻塞 同步 异步

    一开始接触这几个概念会感觉有些困惑, 但抓住应用程序线程, 操作系统的线程以及内存的内核空间用户空间这几个概念就好了.一个IO操作需要操作系统线程将数据准备好, 并将数据从内核空间复制到用户空间. 具体过程:首先一个IO请求由应用程序线程发起, 接着操作系统的线程会将数据在内存的内核空间将数据准备好, 然后再从内核空间拷贝至用户空间, 供应用程序的线程读取.

    1. 阻塞
      阻塞是指应用程序的线程在IO操作处阻塞, 而不能进行往下执行.
    2. 非阻塞
      非阻塞则是, 就算操作系统的线程还未将IO操作的数据准备好,应用程序的线程还能够继续汪下执行.
    3. 同步
      同步本身是指多个线程之间的同步. 在IO操作中是指应用程序的线程是指需要不断的去询问操作系统线程IO操作的数据是否准备好.
    4. 异步
      相对同步, 异步则是程序的线程不用不断询问操作系统的线程数据时候准备好, 而是一旦操作系统的线程将数据准备好准备好了, 操作系统的线程会主动通知应用程序的线程. 异步需要操作系统的内核线程给与更多的支持.

    BIO NIO AIO的应用场景2

    BIO NIO AIO都有自己的应用场景, BIO性能低下, 适合连接数量少, 连接小的场景;

    • BIO 方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中, JDK1.4以前的唯一选择,但程序简单易理解。

    • NIO 方式适用于连接数目多且连接比较短(轻操作) 的架构, 比如聊天服务器, 弹幕系统, 服务器间通讯等。编程比较复杂, JDK1.4 开始支持。

    • AIO 方式使用于连接数目多且连接比较长 (重操作) 的架构, 比如相册服务器, 充分调用 0S 参与并发操作,编程比较复杂, JDK7 开始支持。

      AIO需要更加依赖操作系统的支持, 但Linux操作系统从2.6版本才开始支持AIO, 现在还不如windos的完善, 在高并发网络编程中依然以IO复用模式为主.

    NIO解读

    NIO是一种单线程的多路复用IO, 其通过selector选择器监听多个连接, 一旦有连接需要处理则往下执行依次处理这些连接请求, 处理完之后再此循环至selector处查看是否有请求需要处理, 整个过程为单线程, 涉及线程切换.

    虽然NIO的selector也会阻塞线程, 但是其依然叫同步非阻塞原因在于它可以同时监听多个IO操作, 在一些IO操作数据还没准备好的时候, 可以去处理其它IO操作, 并不会被某一个IO操作阻塞, 因此称为非阻塞IO, 这也是它被称为多路复用的原因.
    下面是一个简单的代码示例:

    public class NIOServer extends Thread {
    
    	public void run() {
    	try (Selector selector = Selector.open(); // 创建Selector
    	ServerSocketChannel serverSocket = ServerSocketChannel.open();) {  // 创建服务器socket
    	serverSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), 8888));// 绑定IP地址与端口
    	serverSocket.configureBlocking(false);  // 将服务器socket设置为非阻塞
    	
    	serverSocket.register(selector, SelectionKey.OP_ACCEPT);  // 注册selector
    	
    	while (true) {
    		selector.select();// 监测是否有连接
    		
    		Set<SelectionKey> selectedKeys = selector.selectedKeys();
    		Iterator<SelectionKey> iter = selectedKeys.iterator();
    		while (iter.hasNext()) {// 遍历处理连接
    		SelectionKey key = iter.next();
    		requestHandler((ServerSocketChannel) key.channel());
    		iter.remove();
    		}
    	}
    }
    

    参考

    1. http://www.52im.net/thread-306-1-1.html
    2. https://www.bilibili.com/video/av76227904?p=4
    3. https://juejin.im/post/5bea1d2e51882523d3163657
    4. https://www.jianshu.com/p/2965fca6bb8f
  • 相关阅读:
    差分约束+SPFA+栈
    差分约束问题讲解博客
    最小费用最大流2
    最小费用最大流
    合并油田
    PHP核心技术与最佳实践--笔记
    PHP命令行模式
    vim一些常用的快捷键
    varnish 的一个配置
    redis在我工作中的实际应用
  • 原文地址:https://www.cnblogs.com/bitbitbyte/p/12536573.html
Copyright © 2011-2022 走看看