首页 > 编程语言 >javaAIO是什么

javaAIO是什么

时间:2023-05-06 10:57:46浏览次数:43  
标签:异步 java javaAIO 什么 线程 IO import ByteBuffer

网络IO进行时,需要将用户态切换为内核态,操作系统内核在进行网络IO时有等待数据、拷贝数据两个阶段。

无论是阻塞IO、非阻塞IO、多路复用,都是同步IO,因为他们都是等数据准备好了,再使用当前线程去获取数据。

IO类型 等待数据阶段 拷贝数据阶段 用户态和内核态切换次数
阻塞IO read方法阻塞 阻塞 1次
非阻塞IO 没有数据到来read方法也不会阻塞,而是返回0,有数据到来read方法则有大于0的返回值 阻塞 N次(得循环向内核请求是否有数据到来)
多路复用 select方法阻塞,但是selector跳过了所有请求的数据等待阶段,一旦select方法解除阻塞,所有数据已经到来的channel都可以进行数据拷贝(相当于数据等待阶段是异步回调机制实现的,但是数据拷贝阶段还是阻塞进行的) 阻塞 2次(一次注册selector,一次拷贝数据)

AIO意为异步IO,即以上两个阶段都交由异步线程去处理,不能阻塞当前线程。然后在异步线程中加入一个回调函数,表示在收到数据后应该执行的操作。

(AIO很像一个异步线程的 JdbcTemplate.query(String sql, RowMapper<T> rowMapper),将所有拿到数据后的操作放到rowMapper中,再把这个方法放在一个异步线程或线程池中运行)

AIO的异步并不是在一次IO内部的异步,而是相对于当前线程的异步以及不同IO之间不阻塞。比如当前线程负责了所有事件的处理,发现两个客户端都需要read操作,在同步IO中,无论是哪种同步IO类型,都是在一个线程中执行,拷贝数据阶段一定有先后顺序,且一定会阻塞accept,其他客户端连都连不上;而在异步IO中,所有的操作都交由异步线程处理,read操作在异步线程中处理,不会阻塞accept事件,accept发生时,创建连接的操作也是异步线程来处理。

AIO简单示例如下:

1、文件异步IO

package net.yury.aio;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * 异步IO是指数据的等待和拷贝都交由另外一个线程执行,再给另外一个线程一个回调函数,告诉他数据准备好了就执行这个回调函数,我这边就可以得到响应。
 */
public class FileAIO {
    public static void main(String[] args) {
        try(AsynchronousFileChannel channel = AsynchronousFileChannel.open(Paths.get("test.txt"),StandardOpenOption.READ)) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            System.out.println("[" + Thread.currentThread().getName() + "] begin read");
            channel.read(buffer, 0, null, new CompletionHandler<Integer, ByteBuffer>() {

                @Override
                public void completed(Integer result, ByteBuffer attachment) {
                    buffer.flip();
                    System.out.println("[" + Thread.currentThread().getName() + "] file content is: " + StandardCharsets.UTF_8.decode(buffer).toString());
                }

                @Override
                public void failed(Throwable exc, ByteBuffer attachment) {
                    exc.printStackTrace();
                }
            });
            System.out.println("[" + Thread.currentThread().getName() + "] finish read");
            System.in.read();
        }catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

2、网络异步IO

package net.yury.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.StandardCharsets;

/**
 * 代码还有点问题,会报错
 */
public class NetAIO {

    public static void main(String[] args) throws IOException {
        // 是不是很像netty的handler
        CompletionHandler<Integer, ByteBuffer> handler = new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                attachment.flip();
                System.out.println(StandardCharsets.UTF_8.decode(attachment).toString());
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                System.out.println("error1");
                exc.printStackTrace();
            }
        };

        try (AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open()) {
            listener.bind(new InetSocketAddress("0.0.0.0", 8080));

            listener.accept(null, new CompletionHandler<AsynchronousSocketChannel, ByteBuffer>() {
                @Override
                public void completed(AsynchronousSocketChannel channel, ByteBuffer attachment) {
                    listener.accept(null, this);
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    channel.read(buffer, buffer, handler);
                }

                @Override
                public void failed(Throwable exc, ByteBuffer attachment) {
                    System.out.println("error2");
                    exc.printStackTrace();
                }
            });
        }catch (IOException ex) {
            System.out.println("error3");
            ex.printStackTrace();
        }
        System.in.read();
    }
}

标签:异步,java,javaAIO,什么,线程,IO,import,ByteBuffer
From: https://www.cnblogs.com/yury757/p/17376571.html

相关文章

  • count(列名)、count(1)和 count(*)有什么区别?
    在MySQL中,这几个都是统计操作,很多人在使用的时候,都使用的是count(1),这有没有问题?使用正确?达到了统计效果?我们从效果和效率两方面来分析下执行效果count(*)包括了所有的列,在统计时不会忽略列值为null的数据count(1)用1表示代码行,在统计时不会忽略列值为null的数据co......
  • java基础-什么是方法,方法的定义和调用,方法的重载,方法的内存
    一、什么是方法方法method是程序中最小的执行单元。在实际开发中,可以将重复的代码、具有独立功能的代码抽取到方法中,这样可以提高代码的复用性和可维护性。二、方法的定义(打包)和调用注意:方法要写在main主方法的外面(在main方法外面定义)。1、最简单的方法定义和调用//最简单......
  • pytes中fixture的scope: 决定可以在什么范围内共享fixture
    1fixture的scope在@pytest.fixture(scope='xxx')中,scope的可选值有5个,以下是官网的描述2function级别的scope添加如下代码到pytest.ini,便于输出日志新建conftest.py文件,把fixture函数写入其中,便于后面fixture可以在多个py文件中的test函数中引用conftest.pypytest的fix......
  • windows api编程中 常用变量名pszText 的 psz 代表什么意思
    来自ChatGPT的回答:在WindowsAPI编程中,pszText是一个常见的变量名,通常用于表示一个指向包含文本字符串的缓冲区的指针。其中,psz是一种常见的命名前缀,它代表“指向以零结尾的字符串指针(PointertoZero-terminatedString)”。这是因为在WindowsAPI中,许多函数和结构体成员都需要......
  • MASA MinimalAPI源码解析:为什么我们只写了一个app.MapGet,却生成了三个接口
    源码解析:为什么我们只写了一个app.MapGet,却生成了三个接口1.ServiceBase1.AutoMapRoute源码如下:AutoMapRoute自动创建map路由,MinimalAPI会根据service中的方法,创建对应的api接口。比如上文的一个方法:publicasyncTask<WeatherForecast[]>PostWeather(){re......
  • 智能工单系统有什么作用?
    智能工单系统作为辅助企业处理客户问题的重要工具,能够满足企业为客户提供高效服务的需求。及时响应服务需求,智能传递和分发工单,实现公司各部门线上线下服务的高效协同,快速解决用户问题。那么智能工单系统有什么作用?1、打破服务缺口,让客户“零”等待在互联网时代,企业面临的信息是......
  • pod 的GVK 是什么
    pod的GVK是什么在Kubernetes中,GVK是指Group、Version和Kind三个字段,用于唯一标识Kubernetes资源对象。Group指的是KubernetesAPI中的资源组,例如apps、batch、core等。Version指的是资源对象的API版本,例如v1、v1beta1、v2alpha1等。Kind指......
  • 什么是OV代码签名证书?什么是“硬证书”?
    代码签名证书用于对软件代码进行数字签名,保护代码完整性、防止非法篡改;标识软件发行商的身份、确保软件来源可信。按不同验证级别,代码签名证书分为扩展验证型EV代码签名证书、企业验证型OV代码签名证书。什么是OV代码签名证书?OV代码签名证书,是指OV(OrganizationValidation)企业验证......
  • Java中为什么要使用Integer呢?阐述Integer与int的区别
    (1)设计Integer封装类型的原因是:Java本身就是一个面向对象的编程语言,一切操作都是以对象作为基础,如像ArrayList,HashSet,Hashtable,HashMap等集合类中存储的元素,只支持存储Object类型,又如同泛型的设计,统统表现出了Java对于封装类型的重用,而对于int,byte,short,float,char,long,double这......
  • 到底什么是小程序插件?
    最近和小伙伴交流,时常发生插件、组件、控件等概念混淆的情况,因此导致经常会错意。感觉还是很有必要带大家整理清楚的,今天就来跟大家来聊一聊插件、组件、控件的区别。什么是插件先按照官方的一些解释来看看插件的概念描述?微信小程序官方描述:插件,是可被添加到小程序内直接使用......