Java AsynchronousFileChannel - 线程使用

2023-11-26

我理解Java的AsynchronousFileChannel是一个异步api(不会阻塞调用线程)并且可以使用系统线程池中的线程。

我的问题是:AsynchronousFileChannel 操作是否具有 1:1 的线程比?

换句话说,如果一个循环使用 AsynchronousFileChannel 读取 100 个文件,它会使用 100 个线程来执行此操作还是仅使用少量线程(以标准 NIO 方式)?


AsynchronousFileChannel一般使用的实现(以及实际使用的,例如在Linux上)是简单的异步 FileChannelImpl基本上提交Runnables在同一个线程中执行阻塞 IO 读取+处理的结果(要么填充 future 要么调用CompletionHandler) to an ExecutorService其中任一作为参数提供AsynchronousFileChannel::open,否则使用默认的系统范围的(is无界缓存线程池,但有一些选项可以配置). Some think这是对文件可以完成的最好的操作,因为它们“始终可读”,或者至少操作系统没有提供任何它们不可读的线索。

在 Windows 上,使用一个单独的实现,称为Windows 异步 FileChannelImpl。它用I/O 完成端口又名 IOCP,在 Windows Vista/2008 及更高版本(主要版本 >=“6”)上运行时,通常表现得更像您所期望的:默认情况下,它使用 1 个线程来分派读取结果(可通过以下方式配置)"sun.nio.ch.internalThreadPoolSize"系统属性)和用于处理的缓存线程池。

So, 回答你的问题: 如果你不提供自己的ExecutorService(说一个固定的)AsynchronousFileChannel::open,那么就会是1:1的关系,所以100个文件就有100个线程;除了非古老的 ​​Windows,默认情况下会有 1 个线程处理 I/O,但如果所有结果同时到达(不太可能但仍然如此)并且您使用CompletionHandlers,它们也将在自己的线程中被调用。

Edit:我实现了对 100 个文件的读取,并在 Linux 和 Windows (openjdk8) 上运行它,它 1) 确认了两者上实际使用了哪些类(对于删除TF.class同时仍然在命令行中指定它并查看堆栈跟踪),2)排序确认使用的线程数:Linux 上为 100,如果完成处理速度很快,则 Windows 上为 4(如果CompletionHandlers未使用),如果完成处理很慢,则在 Windows 上为 100。尽管它很丑陋,但代码是:

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.file.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.*;

public class AsynchFileChannelDemo {

    public static final AtomicInteger ai = new AtomicInteger();

    public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
        final List<ByteBuffer> bufs = Collections.synchronizedList(new ArrayList<>());
        for (int i = 0; i < 100; i++) {
            Path p = Paths.get("some" + i + ".txt");
            final ByteBuffer buf = ByteBuffer.allocate(1000000);
            AsynchronousFileChannel ch = AsynchronousFileChannel.open(p, StandardOpenOption.READ);
            ch.read(buf, 0, buf, new CompletionHandler<Integer, ByteBuffer>() {
                @Override
                public void completed(Integer result, ByteBuffer attachment) {
                  bufs.add(buf);
                  // put Thread.sleep(10000) here to make it "long"
                }

                @Override
                public void failed(Throwable exc, ByteBuffer attachment) {
                }
            });
        }
        if (args.length > 100) System.out.println(bufs); // never
        System.out.println(ai.get());
    }
}

and

import java.util.concurrent.ThreadFactory;

public class TF implements ThreadFactory {
    @Override
    public Thread newThread(Runnable r) {
        AsynchFileChannelDemo.ai.incrementAndGet();
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t;
    }
}

编译这些,将它们放在一个包含 100 个文件的文件夹中,名为some0.txt to some99.txt,每个大小为 1Mb,因此读取速度不会太快,运行如下

java -Djava.nio.channels.DefaultThreadPool.threadFactory=TF AsynchFileChannelDemo

打印的数字是线程工厂创建新线程的次数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java AsynchronousFileChannel - 线程使用 的相关文章

  • 如何修复安装 maven jar 插件依赖项时出现的错误?

    我正在将应用程序制作成 maven 中的 jar 文件 但是 当我从 Maven 中提取 jar 插件存储库并在终端中运行这三个命令时 mvn clean mvn compile mvn package 在 mvn package 中 我收
  • 单击链接时如何将另一个 JSP 页面注入到

    我在一个JSP页面中有两个不同的部分 其中一个包含链接菜单 单击时 div2 id content 会相应加载不同的页面 我正在做类似的事情 div ul class navbar li a href Login jsp Login a l
  • 如何在Java中使用我的密码加密和解密字符串(PC而非移动平台)? [复制]

    这个问题在这里已经有答案了 我想加密一个字符串然后将其放入文件中 当我想要的时候也想解密它 我不需要很强的安全性 我只是想让其他人更难获取我的数据 我尝试了几种方法 这是这些 Md5加密 如何在 Android 中对字符串进行哈希处理 ht
  • JTree 避免重新加载后崩溃

    我正在尝试找到解决崩溃问题的方法JTree重新加载后 情况 JTree Office A Office A 1 Office A 1 1 Office A 1 2 Office B Office B 1 Office B 1 1 Offic
  • 克隆 dom.Document 对象

    我的目的是将xml文件读入Dom对象 编辑dom对象 其中涉及删除一些节点 完成此操作后 我希望将 Dom 恢复到其原始状态 而不实际解析 XML 文件 无论如何 我可以克隆第一次解析 xml 文件后获得的 dom 对象吗 这个想法是避免一
  • android.os.FileUriExposedException 在 Oreo 中引起(仅!)[重复]

    这个问题在这里已经有答案了 从 Google Play Console 中 我可以看到此异常仅发生在 Android 8 0 的设备上 android os FileUriExposedException at android os Str
  • 从 java 类生成 xsd 的实用程序

    我想为以下类生成 xsd public class Node private String value private List
  • 枚举内的枚举

    这不是我被卡住的问题 而是我正在寻找一种简洁的方式来编写我的代码 本质上 我正在编写一个事件驱动的应用程序 用户触发事件 事件被发送到适当的对象 然后对象处理事件 现在我正在编写偶数处理程序方法 我希望使用 switch 语句来确定如何处理
  • docker 中带有参数的 jar 文件

    Helo 我有一个 java jar 文件 当我从终端运行它时 它会接受一堆参数作为输入 我想制作一个 docker 映像并运行它 其中包含 jar 文件 我仍然可以在其中传递 jar 文件的参数 将 jar 文件设置为您的入口点 http
  • 在Java中读取制表符分隔的文件

    我有以下代码来读取 Java 中的制表符分隔文件 while str in readLine null if str trim length 0 continue String values str split t System out p
  • 如何将点击侦听器添加到 Android/Java Textview 中的字符串中?

    我想要完成的是大多数 Twitter 应用程序中的标准操作 在文本视图中 文本字符串中的单词前面可能有 提及或 主题标签 并且它们实际上能够添加点击侦听器这个词启动了另一项活动 有谁知道这是如何实现的 下面我附上了一张示例照片 显示了我想要
  • 如何使用jdbc驱动编写事务?

    我想使用 jdbc 编写一个事务java 我尝试过这个简单的交易 BEGIN TRANSACTION NL GO NL UPDATE table SET col test where id 1010 NL GO NL COMMIT 我尝试过
  • MongoDb Spring 在嵌套对象中查找

    我正在使用 Spring Data Mongodb 和这样的文档 id ObjectId 565c5ed433a140520cdedd7f attributes 565c5ed433a140520cdedd73 333563851 list
  • 检查对象是否为空

    我有一个链表 其中第一个节点包含空对象 表示firstNode data等于null firstNode nextPointer null firstNode previousPointer null 我想检查firstNode 是否为空
  • Spring Boot - 如何在开发过程中禁用@Cacheable?

    我正在寻找两件事 如何在开发过程中使用 Spring boot dev 配置文件禁用所有缓存 application properties 中似乎没有通用设置可以将其全部关闭 最简单的方法是什么 如何禁用特定方法的缓存 我尝试像这样使用 S
  • oracle.jdbc.driver.OracleDriver ClassNotFoundException

    这是我收到错误的代码 我的classes12 jar已作为外部 jar 导入 import java io IOException import java io PrintWriter import java sql Connection
  • 为什么这段代码可以在 Java 7 中运行,而不能在 Java 8 中运行?

    我目前使用 IDE Eclipse 版本 Neon 2 Release 4 6 2 和版本 java Version 8 Update 131 在此代码中 IDE 给出错误 类型不匹配 无法从字节转换为整数 Integer i byte 1
  • Maven编译错误:包不存在

    我正在尝试向现有企业项目添加 Maven 支持 这是一个多模块项目 前 2 个模块编译和打包没有问题 但我面临编译错误 我尝试在多个模块中使用相同的依赖项 我的结构是 gt parent gt pom xml gt module 1 gt
  • 在Java中,为什么某些变量首先需要初始化,而其他变量只需要声明?

    我试图更深入地理解我是否遗漏了一些关于 Java 何时需要变量初始化与简单声明的理解 在以下代码中 不需要为变量 row 赋值即可编译和运行 但变量 column 则需要赋值 注意 该程序没有任何用处 它已被修剪为仅显示此问题所需的内容 以
  • Encog:BasicNetwork:无需预先构建数据集的在线学习

    我正在尝试使用 encog 库作为强化学习问题的函数逼近器 更准确地说 我正在尝试启动并运行多层感知器 BasicNetwork 由于我的代理将根据我选择的任何 RL 算法以某种方式探索世界 因此我无法预先构建任何 BasicNeuralD

随机推荐

  • Spark Streaming:StreamingContext不读取数据文件

    我是 Spark Streaming 的新手 我正在尝试使用 Spark shell 开始使用它 假设我在spark 1 2 0 bin hadoop2 4的根目录下放置了一个名为 dataTest 的目录 我想在 shell 中测试的简单
  • Service Worker 中的 XMLHttpRequest

    我正在尝试在 chrome 上创建一个推送通知系统 我有一个从 mysql 获取数据并回显 JSON 的 php 现在我想调用一个函数 getJsonCode 当推送通知到达时它会被激活并读取 JSON 数据 在我的 Service Wor
  • 如何手动将 Angular 表单字段设置为无效?

    我正在处理登录表单 如果用户输入无效凭据 我们希望将电子邮件和密码字段标记为无效 并显示一条消息 提示登录失败 如何从可观察的回调中将这些字段设置为无效 模板
  • Hibernate 忽略 fetchgraph

    这是我的实体 public class PersonItem implements Serializable Id Column name col1 private String guid Column name col2 private
  • 如何通过将值与公共键相加来从字典列表创建单个Python字典?

    我有一个字典列表 例如 dictList a 3 b 9 c 4 a 9 b 24 c 99 a 10 b 23 c 88 所有字典都有相同的键 例如a b c 我希望创建一个具有相同键的字典 其中的值是原始列表中所有字典中具有相同键的值的
  • 如果没有输入,一定时间后退出循环

    我只是想知道是否可能以及如何实现此功能 如果没有用户输入 我们将退出循环 例如 如果用户在 1 分钟后没有输入任何内容 我想退出循环 这是我的 C 代码 include
  • 如何直接链接到应用商店应用更新页面?

    我正在完成一个 iPhone 应用程序 我使用外部服务器通知用户我的应用程序何时有可用更新 并允许他们从应用程序内单击以直接转到应用程序商店中的更新 问题是 我似乎无法弄清楚直接转到更新的链接格式 我发现了一种旧的使用方法查看软件更新 在另
  • 在 javascript 中使用另一个 fetch 中的 fetch

    我想获取一个 api 然后调用另一个 api 在 javascript 中使用这样的代码是否明智 fetch url method get then function response response json then function
  • 新 Twitter API 1.1 的身份验证

    我有一个应用程序需要显示关注者和关注者的数量 users show json 对于公共页面上的随机用户 不需要身份验证 使用 Twitter API 1 0 这非常容易 因为请求不需要身份验证 使用新的 Twitter API 1 1 不再
  • Sql Server FILESTREAM 总文件大小

    是否有一个查询可以获取磁盘上 FILESTREAM 文件夹中文件的总文件大小 以下查询将返回以字节为单位的长度filestreamcolumn column SELECT SUM DATALENGTH filestreamcolumn FR
  • 使用另一个对象更新 javascript 对象,但仅更新现有的键

    Javascript 或 Lodash 中是否有一个函数 我可以在其中使用另一个对象的值 更新 一个对象 但是无需添加新密钥 var foo a 0 b 1 var bar b 2 c 3 像 update foo bar 一样 覆盖 更新
  • JAX-RS - 没有根节点的 JSON

    我有一个宁静的网络服务 响应是 cities id 1 name City 01 state A1 id 2 name City 02 state A1 但我想要这个 id 1 name City 01 state A1 id 2 name
  • JOptionPane 输入到 int

    我试图让 JOptionPane 获取输入并将其分配给 int 但我遇到了变量类型的一些问题 我正在尝试这样的事情 Int ans Integer JOptionPane showInputDialog frame Text JOption
  • 如何从写成单词的数字中读取值?

    众所周知 数字可以用数字来书写 也可以用名称来称呼 虽然有很多将 123 转换为 123 的示例 但我找不到如何将其反向转换的好示例 一些注意事项 基数 名义或序数 一 和 第一 常见的拼写错误 四十 四十 数百 千 2100 gt 二十一
  • 如何知道鼠标左键是否被按下

    我正在使用 PyAutoGUI 库 如何知道鼠标左键是否被按下 这就是我想做的 if leftmousebuttonpressed print left else print nothing 我是 PyAutoGUI 的作者 我可以确认当前
  • Android SDK路径未指定

    我已经安装了 android studio 但我在继续操作时遇到问题 问题是Android SDK路径未指定 这是什么意思 我需要下载什么东西还是什么 Android SDK 有问题 请执行以下步骤 但首先确保您的电脑已连接到互联网 打开你
  • Twitter资料页iOS Swift剖析(UIScrollView中的多个UITableView)

    嗨 他们到底是如何实现这个的 Twitter 个人资料页面有几个教程 但他们并没有处理所有的可能性 首先 当您滚动顶部或底部任何位置时 顶部视图开始滚动 直到分段控件 到达页面顶部 然后滚动不会停止 子表开始滚动 直到触地并在中间表视图开始
  • Linux 动态链接器中的“无版本信息可用”错误是什么意思?

    在我们的产品中 我们提供了一些动态链接到 libpam 等系统库的 Linux 二进制文件 在某些客户系统上 当程序运行时 我们会在 stderr 上收到以下错误 authpam lib libpam so 0 no version inf
  • UICollectionViewCell 按固有大小展开/折叠

    I have a collection view with a custom flow layout and many different cells of different height The width of the collect
  • Java AsynchronousFileChannel - 线程使用

    我理解Java的AsynchronousFileChannel是一个异步api 不会阻塞调用线程 并且可以使用系统线程池中的线程 我的问题是 AsynchronousFileChannel 操作是否具有 1 1 的线程比 换句话说 如果一个