Java 执行器:当任务完成时,如何在不阻塞的情况下收到通知?

2023-12-28

假设我有一个充满任务的队列,我需要将其提交给执行器服务。我希望一次处理一个。我能想到的最简单的方法是:

  1. 从队列中取出一个任务
  2. 提交给执行人
  3. 对返回的 Future 调用 .get 并阻塞,直到有结果可用
  4. 从队列中取出另一个任务...

但是,我试图完全避免阻塞。如果我有 10,000 个这样的队列,它们需要一次处理一个任务,那么我将耗尽堆栈空间,因为它们中的大多数将保留阻塞的线程。

我想要的是提交任务并提供任务完成时调用的回调。我将使用该回调通知作为发送下一个任务的标志。 (functionjava和jetlang显然使用了这种非阻塞算法,但我无法理解他们的代码)

如果不编写自己的执行器服务,如何使用 JDK 的 java.util.concurrent 来做到这一点?

(为我提供这些任务的队列本身可能会阻塞,但这是一个稍后要解决的问题)


定义一个回调接口来接收您想要在完成通知中传递的任何参数。然后在任务结束时调用它。

您甚至可以为可运行任务编写通用包装器,并将它们提交给ExecutorService。或者,请参阅下文了解 Java 8 中内置的机制。

class CallbackTask implements Runnable {

  private final Runnable task;

  private final Callback callback;

  CallbackTask(Runnable task, Callback callback) {
    this.task = task;
    this.callback = callback;
  }

  public void run() {
    task.run();
    callback.complete();
  }

}

With CompletableFuture http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html,Java 8 包含了一种更复杂的方法来组成管道,其中流程可以异步且有条件地完成。这是一个人为但完整的通知示例。

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

public class GetTaskNotificationWithoutBlocking {

  public static void main(String... argv) throws Exception {
    ExampleService svc = new ExampleService();
    GetTaskNotificationWithoutBlocking listener = new GetTaskNotificationWithoutBlocking();
    CompletableFuture<String> f = CompletableFuture.supplyAsync(svc::work);
    f.thenAccept(listener::notify);
    System.out.println("Exiting main()");
  }

  void notify(String msg) {
    System.out.println("Received message: " + msg);
  }

}

class ExampleService {

  String work() {
    sleep(7000, TimeUnit.MILLISECONDS); /* Pretend to be busy... */
    char[] str = new char[5];
    ThreadLocalRandom current = ThreadLocalRandom.current();
    for (int idx = 0; idx < str.length; ++idx)
      str[idx] = (char) ('A' + current.nextInt(26));
    String msg = new String(str);
    System.out.println("Generated message: " + msg);
    return msg;
  }

  public static void sleep(long average, TimeUnit unit) {
    String name = Thread.currentThread().getName();
    long timeout = Math.min(exponential(average), Math.multiplyExact(10, average));
    System.out.printf("%s sleeping %d %s...%n", name, timeout, unit);
    try {
      unit.sleep(timeout);
      System.out.println(name + " awoke.");
    } catch (InterruptedException abort) {
      Thread.currentThread().interrupt();
      System.out.println(name + " interrupted.");
    }
  }

  public static long exponential(long avg) {
    return (long) (avg * -Math.log(1 - ThreadLocalRandom.current().nextDouble()));
  }

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

Java 执行器:当任务完成时,如何在不阻塞的情况下收到通知? 的相关文章

  • 使用 Tabula 通过 Python 读取 pdf 时出现 Java 错误

    我已经安装了 tabula 库 用于使用 python 将 pdf 读取到 pandas 数据框中 但是当我运行代码时 import tabula df tabula read pdf sample1 pdf pages 1 我得到了例外
  • 垃圾收集器如何在幕后工作来收集死对象?

    我正在阅读有关垃圾收集的内容 众所周知 垃圾收集会收集死亡对象并回收内存 我的问题是 Collector 如何知道任何对象已死亡 它使用什么数据结构来跟踪活动对象 我正在研究这个问题 我发现GC实际上会跟踪活动对象 并标记它们 每个未标记的
  • eclipse行号状态行贡献项是如何实现的?

    我需要更新状态行编辑器特定的信息 我已经有了自己的实现 但我想看看 eclipse 贡献项是如何实现的 它显示状态行中的行号 列位置 谁能指点一下 哪里可以找到源代码 提前致谢 亚历克斯 G 我一直在研究它 它非常复杂 我不确定我是否了解完
  • 为什么即使我的哈希码值相同,“==”也会返回 false

    我写了一个像这样的课程 public class HashCodeImpl public int hashCode return 1 public static void main String args TODO Auto generat
  • 将巨大的模式编译成Java

    有两个主要工具提供了将 XSD 模式编译为 Java 的方法 xmlbeans 和 JAXB 问题是 XSD 模式确实很大 30MB 的 XML 文件 大部分模式在我的项目中没有使用 所以我可以注释掉大部分代码 但这不是一个好的解决方案 目
  • Mockito 使用 @Mock 时将 Null 值注入到 Spring bean 中?

    由于我是 Spring Test MVC 的新手 我不明白这个问题 我从以下代码中获取了http markchensblog blogspot in search label Spring http markchensblog blogsp
  • 在 Java 中如何找出哪个对象打开了文件?

    我需要找出答案哪个对象在我的 Java 应用程序中打开了一个文件 这是为了调试 因此欢迎使用工具或实用程序 如果发现哪个对象太具体了 这class也会很有帮助 这可能很棘手 您可以从使用分析器开始 例如VisualVM http visua
  • 断言 Kafka 发送有效

    我正在使用 Spring Boot 编写一个应用程序 因此要写信给 Kafka 我这样做 Autowired private KafkaTemplate
  • 如何在 Spring 中使 @PropertyResource 优先于任何其他 application.properties ?

    我正在尝试在类路径之外添加外部配置属性资源 它应该覆盖任何现有的属性 但以下方法不起作用 SpringBootApplication PropertySource d app properties public class MyClass
  • Sun 在 EDT 之外做 GUI 工作的演示?

    我正在看SplashDemo java http download oracle com javase tutorial uiswing examples misc SplashDemoProject src misc SplashDemo
  • 如何仅从 Firestore 获取最新更新的数据?

    在 Firestore 上发现任何更改时始终获取整个文档 如何只获取最近更新的数据 这是我的数据 我需要在第一次加载时在聊天中按对象顺序 例如 2018 09 17 30 40 msg和sendby 并且如果数据更新则仅获取新的msg和se
  • 如何在 ant 中为 junit 测试设置 file.encoding?

    我还没有完全完成file encoding 和 ant https stackoverflow com questions 1339352 how do i set dfile encoding within ants build xml
  • Akka 与现有 java 项目集成的示例

    如果我已经有现有的javaWeb 应用程序使用spring and servlet容器 将 Akka 集成到其中的正确方法是什么 就像我将会有Actor1 and Actor2互相沟通的 开始使用这些演员的切入点是什么 例如 1 把它放在那
  • 如何使用 JMagick 转换色彩空间?

    如何使用 JMagick API 转换色彩空间 例如 CMYK gt RGB 和 RGB gt CMYK None
  • 不可变的最终变量应该始终是静态的吗? [复制]

    这个问题在这里已经有答案了 在java中 如果一个变量是不可变的并且是final的 那么它应该是一个静态类变量吗 我问这个问题是因为每次类的实例使用它时创建一个新对象似乎很浪费 因为无论如何它总是相同的 Example 每次调用方法时都会创
  • Java Swing - 如何禁用 JPanel?

    我有一些JComponents on a JPanel我想在按下 开始 按钮时禁用所有这些组件 目前 我通过以下方式显式禁用所有组件 component1 setEnabled false 但是有什么办法可以一次性禁用所有组件吗 我尝试禁用
  • 将 JavaFX FXML 对象分组在一起

    非常具有描述性和信息性的答案将从我这里获得价值 50 声望的赏金 我正在 JavaFX 中开发一个应用程序 对于视图 我使用 FXML
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似
  • Java 11 - 将 Spring @PostConstruct 替换为 afterPropertiesSet 或使用 initMethod

    我正在使用 spring 应用程序 有时会使用 PostConstruct用于代码和测试中的设置 看来注释将被排除在外Java 11 https www baeldung com spring postconstruct predestro
  • 由 Servlet 容器提供服务的 WebSocket

    上周我研究了 WebSockets 并对如何使用 Java Servlet API 实现服务器端进行了一些思考 我没有花费太多时间 但在使用 Tomcat 进行一些测试时遇到了以下问题 如果不修补容器或至少对 HttpServletResp

随机推荐

  • 无法解析符号“createFromResource”

    我完全不明白这意味着什么 我已经进行了一些搜索 但到目前为止还没有找到任何帮助 我正在使用 android studio 并有一个对话框片段 我正在其中设置一个微调器 Spinner systemFontSpinner Spinner vi
  • Seaborn 热图更改 yticks 的日期频率

    我的问题与该主题遇到的问题类似 更改多索引数据帧的热图 xticks https stackoverflow com questions 66897981 change heatmaps yticks for multi index dat
  • 本地主机上的谷歌距离矩阵

    我正在尝试使用谷歌距离矩阵来找出从一个源到一个目的地的距离和时间 我正在调用该函数 postCode change function var address sydney var source melbourne var url https
  • EL 中的#{component} 到底是什么?

    根据https code google com p primefaces issues detail id 4720 https code google com p primefaces issues detail id 4720 The
  • GTK信号什么时候发出

    给定从用户连接到回调函数的信号 gtk main 线程将休眠 直到发出信号 我搜索了有关如何或何时发出的详细信息 但找不到任何我不知道的信息 更具体地说 它是异步发出的 以便我可以在某个函数中间调用信号 还是等待特定函数先返回 发出 切换页
  • CKReference 的 CloudKit 订阅通知未按预期工作

    我正在尝试为包含带有用户 CKReference 的字段的记录设置 CKSubscription 但每当创建记录时 它都会忽略compoundPredicate的这一部分 并且通知永远不会出现 在 CKSubscription 的谓词中使用
  • 我可以使用本地文件系统中的图像作为 HTML 的背景吗? [复制]

    这个问题在这里已经有答案了 我有一个托管在远程 Web 服务器上的 HTML 文档 我试图让网页上的元素之一使用本地文件系统中的图像文件作为其背景图像 Chrome Safari 或 Firefox 都不行 还没有尝试过 IE 这是我迄今为
  • 如何通过验证保留 JSF 视图参数

    我将 JSF 2 0 CDI 和 PrimeFaces 2 2 1 用于许多 CRUD 表单 这些表单允许用户通过单击数据表中的链接来查看或更新现有实体的属性 其中实体的标识符被传递到CRUD 形式作为视图参数 我在 PrimeFaces
  • 内存是否加密?

    我想将一些数据存储在变量中 并且我知道变量存储在内存中 内存中的数据是否被加密 另外 软件是否可以读取存储在内存中的变量名称并能够从中实际提取数据 内存是not在我所知道的任何平台上进行加密 无论如何 它的价值有限 因为处理器通常必须对明文
  • R 中 MuMIn 包的标准化

    我使用 R 中的 MuMIn 包来选择模型并计算输入变量 rain brk onset wid 的效应大小 为了使变量之间的效应大小具有可比性 我使用标准化函数对它们进行了标准化arm包裹 这是我正在遵循的代码 供参考 请参阅本文附录 ht
  • StreamReader 和二进制数据

    我有这个包含不同字段的文本文件 某些字段可能包含二进制数据 我需要获取文件中的所有数据 但现在使用 StreamReader 时 它不会读取二进制数据块以及之后的数据 解决这个问题的最佳解决方案是什么 Example field1 fiel
  • 使用 Java 8 的复杂自定义收集器

    我有一个对象流 我想通过以下方式收集它们 假设我们正在处理论坛posts class Post private Date time private Data data 我想创建一个列表 其中包含哪些组posts通过一段时间 如果没有post
  • 使用 Java 通过 Rest API 在 Confluence 中创建页面

    有谁有关于如何使用 Confluence 的 RESTful API 在 Confluence 中创建页面 wiki 条目的示例吗 我正在尝试用 Java 编写一些可以做到这一点的东西 先感谢您 谢谢 我已经在线检查了文档 但找不到任何示例
  • 安装同一 iPhone 项目的不同版本?

    当我制作游戏原型时 我经常需要回去与旧版本进行比较 以更好地了解我是否走在正确的轨道上 但每次我需要检查特定版本时都必须检查旧版本并重新导出 这是一个漫长的过程 如果我可以简单地启动不同的版本 那就会更顺利 如何在设备上安装同一项目的多个版
  • 如果在沙盒中,Stripe.js 需要“allow-same-origin”

    我正在尝试打开stripe js的支付网关 结账页面 我这样做了 async function LoadPaymentController var stripe Stripe pk test 51JBxkrB1SsiUQAfnzEWMqNg
  • 从 url 中删除 php 扩展名

    我有网址example com lt php example并希望删除 phpexample com lt example我尝试使用 htaccess 但我认为这是不可能的 RewriteEngine On RewriteCond REQU
  • 是否可以使 SwiftUI ListMenu 具有不同的行为?

    是否可以使用 swiftUI 创建一个列表菜单 其中列表项具有不同的行为 并使用 foreach 添加到视图中 列表项将是模型 例如 第一个将打开 个人资料 视图 第二个将打开另一个不同的视图 第三个将只是简单地注销 并用 ForEach
  • 使用正则表达式提取 PHP 代码

    我想用正则表达式提取本节的整个 PHP 代码 h1 Extract the PHP Code h1 Another stumbling block gt echo that works gt p Some HTML text p 不幸的是
  • Python 最大函数

    当列表中的项目不是同一类型时 max 函数如何工作 例如以下代码返回 1 3 max 1 52 53 1 3 gt 1 3 在Python2中 不同类型对象的默认比较是使用id它们的类型 通过将对象指针转换为整数获得 这里是来源的链接 ht
  • Java 执行器:当任务完成时,如何在不阻塞的情况下收到通知?

    假设我有一个充满任务的队列 我需要将其提交给执行器服务 我希望一次处理一个 我能想到的最简单的方法是 从队列中取出一个任务 提交给执行人 对返回的 Future 调用 get 并阻塞 直到有结果可用 从队列中取出另一个任务 但是 我试图完全