作为线程调用耗时的 JNI 任务

2024-01-15

我在从线程使用 JNI 调用本机函数时遇到了一个棘手的问题。

本机函数是执行计算密集型任务的遗留代码。由于我不想冻结程序的其余部分,因此计算应该在后台线程中执行。EventBus https://eventbus.dev.java.net/用于将计算结果发送回主程序。

基本上就可以了should很简单,像这样:

public class CalculationEngine {
  private CalculationEngine(){}

  public static void calculateInBackground(final Parameters parameters) {

    new Thread(new Runnable() {
      public void run() {
        // Someone might change the parameters while our thread is running, so:
        final Parameters clonedParameters = parameters.clone();
        Results results = new Results();
        natCalc(clonedParameters, results);
        EventBus.publish("Results", results);
      }
    }).start();

  }

  public static void calculateNormally(final Parameters parameters) {
    Results results = new Results();
    natCalc(parameters, results);
    EventBus.publish("Results", results);
  }

  private static native synchronized void
    natCalc(Parameters parameters, Results results);      
}

现在calculateNormally阻止主程序的方法工作正常,但是calculateInBackground方法,它只是构造一个后台线程来做同样的事情,导致本机代码中出现各种崩溃当连续调用时。我所说的连续是指只有在前一个线程完成并返回结果后才会再次调用它。注意本机代码已标记synchronized以确保一次只能运行一个实例。

我的问题是,本机代码到底是如何根据是从主线程调用还是从其他线程调用而表现不同的?当从主线程以外的线程中调用本机代码时,就像本机代码保持“状态”,而不是真正退出。有没有办法在线程完成后“清理”或“冲洗”线程? JNI 和线程中一定有一些我根本不知道的东西。

感谢您的任何提示!


在谷歌搜索并找到这个短语后,我找到了一个可行的解决方案“我发现 JNI 在从单独的线程调用时存在很多错误......因此请确保只有一个线程调用您的本机代码!” http://bytes.com/groups/java/16934-jni-java-threads。这似乎是真的;解决方案是保留一个持久的、“可重用”的线程 - 我用过Executors.newSingleThreadExecutor()- 并仅从该线程调用本机代码。有用。

因此,从 JNI 的角度来看,区别不在于主线程与其他线程之间,而在于在连续调用中使用不同的线程。请注意,在有问题的代码中,每次都会构造一个新线程。它应该这样工作,但事实并非如此。 (不,我没有缓存 JNIEnv 指针。)

无论是 JNI 错误、本机代码中的错误、它们与操作系统之间的交互还是其他什么,都值得了解。但有时您只是没有机会详细调试 10000 多行现有代码,但是您很高兴让它工作。这是示例代码的工作版本,我们称其为解决方法:

public class CalculationEngine {
  private CalculationEngine(){}

  private static Parameters parameters;
  private static ExecutorService executor = Executors.newSingleThreadExecutor();

  private static Runnable analysis = new Runnable() {
      public synchronized void run() {
        Results results = new Results();
        natCalc(parameters, results);
        EventBus.publish("Results", results);
      }
  };  

  public static synchronized void
    calculateInBackground(final Parameters parameters) {
      CalculationEngine.parameters = parameters.clone();
      executor.submit(analysis);
  }

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

作为线程调用耗时的 JNI 任务 的相关文章

  • NSCondition 是如何工作的?

    我在这个意义上使用 NSCondition 类 void method1 cocoaCondition lock lock while someCheckIsTrue cocoaCondition wait Do something coc
  • C、如何使用pthread_create函数创建线程

    我正在为调度队列创建一个 c 文件 该队列获取任务并将其放入链表队列中 为了做到这一点 我需要使用创建线程 pthread t cThread if pthread create cThread NULL work param perror
  • 线程安全区域设置技术

    我们目前正在编写一个基于线程 python Web 服务器框架 cherrypy 的 Web 应用程序 并希望同时支持来自多个区域设置的用户 区域设置模块似乎不是线程安全的 是否有第三方库或模块以线程安全的方式提供区域设置解析和格式化功能
  • 为什么不允许使用 lock(),但允许使用 Monitor.Enter()?

    对于以下代码 我收到编译时错误 int 不是引用类型 lock 语句所要求的 int i 0 lock i 但没有错误 int i 0 Monitor Enter i 据我所知 由于装箱引起的复杂性 值类型不应该用于锁定 但是 那为什么它可
  • 了解 Numpy 中的向量化与通过 Numexpr 进行向量化表达式的多线程处理之间的区别

    我对 NumPy 据说正在向量化其算术数组运算的概念感到有点挣扎 它是否克服了 Python 的 GIL 因为 NumPy 的一部分是用 C 实现的 另外 Numexpr 是如何工作的呢 如果我理解正确的话 它通过优化 JIT 运行代码并启
  • Java 中的原子整数和普通不可变整数类有什么区别?

    由于 Integer 类也是不可变类 并且我们知道不可变类是线程安全的 因此原子整数需要什么 我很困惑 这是否是不可变对象的读取和写入不需要是原子的 而原子整数的读取和写入是原子的原因 这意味着原子类也是线程安全的 当您需要确保只有一个线程
  • 查询Python的threading.Lock是否加锁

    我正在运行一个线程 下面的代码 它启动一个阻塞子进程 为了确保其他线程不会启动相同的子进程 我对此进行了锁定subprocess call称呼 我还希望能够终止这个子进程调用 所以我有一个从其他地方调用的停止函数 如果子进程提前停止 我也想
  • ASP.NET锁定线程的方法

    我正在使用 C 开发 ASP NET 表单 Web 应用程序 我有一种为客户创建新订单的方法 它看起来与此类似 private string CreateOrder string userName Fetch current order O
  • 尝试在另一个线程wxpython中创建一个对话框

    我正在另一个线程中运行一个函数 该函数应该填写一个对话框 然后显示它 但只要我尝试以任何方式更改对话框 它就会出现段错误 我读到这是 WxPython 的一个常见问题 并且开发人员无意直接更改另一个线程中的对话框 我该如何解决这个问题 我可
  • 在流行的现代操作系统中,线程本地存储是否存在已知的大小限制?

    当我使用thread local Thread local thread or declspec thread 编译器似乎在线程创建时分配一个线程本地存储并将地址存储在fs or gs在 x86 派生系统中注册 在这种情况下 是否存在 线程
  • Android VideoView setVideoURI 阻塞 UI 线程

    Android中VideoView的setVideoURI方法似乎阻塞了UI线程 一旦我调用此方法 即使在快速设备上 UI 也会变得滞后 有没有办法提高这里的性能 我可以在这里找到与该主题相关的唯一其他线程 https groups goo
  • Android GPS 回调关闭 UI 线程

    我无法让 GPS 的 onLocationChanged 在不同的线程上运行 我了解在调用函数时如何管理 UI 线程 但使用 GPS 我不会主动调用该函数 我的目的是每次 GPS 接收到读数时都会有灯光闪烁 我已将此函数放入 Runnabl
  • 单线程应用程序中的同步方法是否较慢?

    在过去的几分钟里 我一直在与自己争论这个问题 我找到了 是 和 否 的理由 这源于查看答案Java HashMap 与 Hashtable https stackoverflow com questions 40471 java hashm
  • .net 中的线程

    我有一个 winforms 应用程序的简单示例 我在目录选择器中选择一个目录 然后单击按钮循环遍历该目录并将目录中的每个文件复制到另一个目录中 我想在后台线程上进行文件复制以避免锁定 GUI 我正在寻找最简单的解决方案 创建后台线程 传递源
  • 在单独的线程中从服务获取 AutoCompleteTextView 建议

    For my AutoCompleteTextView我需要从网络服务获取数据 由于这可能需要一点时间 我不希望 UI 线程没有响应 因此我需要以某种方式在单独的线程中获取数据 例如 从 SQLite DB 获取数据时 使用以下命令非常容易
  • Java中RandomAccessFile的并发

    我正在创建一个RandomAccessFile对象通过多个线程写入文件 在 SSD 上 每个线程都尝试在文件中的特定位置写入直接字节缓冲区 并且我确保线程写入的位置不会与另一个线程重叠 file getChannel write buffe
  • 如何实现具有LinkedHashMap类似功能的ConcurrentHashMap?

    我用过LinkedHashMap with accessOrdertrue 并同时允许最多 500 个条目作为数据的 LRU 缓存 但由于可扩展性问题 我想转向一些线程安全的替代方案 ConcurrentHashMap在这方面似乎不错 但缺
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 使用 JNI 从 Java 代码中检索 String 值的内存泄漏

    我使用 GetStringUTFChars 从使用 JNI 的 java 代码中检索字符串的值 并使用 ReleaseStringUTFChars 释放该字符串 当代码在 JRE 1 4 上运行时 不会出现内存泄漏 但如果相同的代码在 JR
  • 如何正确使用 std::condition_variable?

    我很困惑conditions variables以及如何 安全 使用它们 在我的应用程序中 我有一个创建 gui 线程的类 但是当 gui 是由 gui 线程构造时 主线程需要等待 情况与下面的函数相同 主线程创建互斥体 锁和conditi

随机推荐

  • 带工具提示的 WPF 自定义验证器

    我想为我的 WPF 应用程序创建一个自定义验证器模板 我有一个工具提示模板
  • Linq2Sql 将记录插入相关表

    类似情况 如何使用 LINQ2SQL 添加多个相关记录 https stackoverflow com questions 630320 how to add several dependent records with linq2sql
  • 这里 JavaScript API 3.0 - 如何实现可拖动标记

    我想用最近发布的 JavaScript API 3 0 实现一个可拖动标记 使用旧的 API 非常简单 将draggable 属性设置为true 后 您可以移动地图上的标记 位于 此处 1 的新 API 3 0 的迁移指南指出 在地图对象上
  • 为什么 Android 上的 Chrome 原生 HTML5 日期选择器变得非常慢?

    我的网站上有一个日期选择器 它只使用默认的 html5 日期选择器 我注意到 直到几周前 它都工作正常 但自从 Chrome Android 最近更新后 他们引入了一个新的日期选择器 而这个日期选择器真的很慢而且反应迟钝 加载需要几秒钟 我
  • 如何在Java中扩展final类

    这是我现在面临的实际问题 我有课 比方说Foo这个类定义了一个名为的方法getBar返回一个Bar实例 班上Bar被定义在里面Foo并且 并 被声明public static final 我想做的是定义一个类MyFoo延伸Foo但我也想延长
  • SQL简单减法查询

    我有一个数据库 它包含 2 个表 让我将它们称为表 A 和表 B 表A内容 Date 供应商名称 交付货物名称 交付的货物数量 简单地说是成分 A 数值 表B内容 生产日期 产品名称 成分 A 我真正想要的是 使用表 A 第 4 列减去 减
  • “Options”属性的默认值无法绑定到特定线程

    我发现当我改变班级时 public class MarkdownEditorOptions ObservableObject to public class MarkdownEditorOptions INotifyPropertyChan
  • 插入图像/PNG ggplot2 - Cowplot

    我正在尝试使用cowplot包draw image 功能 我已经设法在图表中获取图像作为示例 我无法弄清楚 xy 位置是如何工作的 我必须不断输入随机数 直到看到图像 require ggplot2 required packages re
  • 更改 Visual Studio 2008 项目中文件夹中整个文件的属性

    我通过从资源管理器中拖放来向我的 Visual Studio 2008 项目添加一个文件夹 我想将该文件夹中整个文件的 复制到输出目录 属性更改为 始终复制 问题是该文件夹包含许多子文件夹 子文件夹也是如此 因此 无法一步阻止所有文件并更改
  • MongoDB 查找精确数组匹配但顺序并不重要

    我正在查询查找精确的数组匹配并成功检索它 但是当我尝试查找具有不同顺序的值的精确数组时 它会失败 Example db coll insert user harsh hobbies 1 2 3 db coll insert user kau
  • 使用 Selenium WebDriver 将鼠标悬停并单击隐藏元素

    当我开始使用 Selenium 时 我发现很难对隐藏元素执行操作 悬停 单击等 这些元素只有在悬停在其他元素上时才可见 所以我希望这对其他人有帮助 您可以使用以下任何一种方法 例如 要upvote此页面中的评论 我需要将鼠标悬停在上下文 即
  • Google API - 如何将 URL 重定向到我的本地主机

    我正在努力使用 Google OAuth 将 google 登录集成到我的 Phonegap 应用程序中 发生的情况是 在为我的应用程序创建客户端 ID 时 我必须选择 已安装的应用程序 然后将应用程序类型选择为 其他 因为我是使用 Pho
  • 可用的游戏网络协议定义语言和代码生成

    我一直在寻找一个好的通用二进制网络协议定义框架 以提供一种用多种语言 例如 Java 后端服务器和 iPhone 前端 编写实时游戏服务器和客户端 例如 魔兽世界 或 雷神之锤 III 的方法用 Objective C 和 Cocoa 编写
  • 从本地文件访问 localStorage

    我正在创建 2HTML文件将存储在本地 iPhone 上并通过WebView 我想知道是否可以设置localStorage在一个文件中 并从另一个文件中获取存储结果 我知道localStorage可以从同一域上的文件访问 但是 您似乎无法从
  • Docker /var/lib/docker/overlay2//merged:没有这样的文件或目录

    我收到以下错误并且找不到任何解决方案 9 builder 3 5 COPY app 9 sha256 deb3e9c3d0d018c2253369e84f48bc653a4796eebadd10de1a2bb60b4954e239 9 ER
  • minwindef.h 中的 IN 和 OUT 宏

    这些在 minwindef h 中定义 通常位于 Program Files x86 Windows Kits 8 1 Include shared minwindef h ifndef IN define IN endif ifndef
  • 为什么 C++ 将 unsigned char 值打印为负数?

    我试图理解 C 中的隐式转换规则 并且我理解当两个主要类型之间存在一个操作时 较低类型 将提升为 较高类型 因此可以这样说 int a 5 float b 0 5 std cout lt lt a b lt lt n 应该打印 5 5 因为
  • 静态上下文无法访问收集器中的非静态上下文

    我有一群学生 首先 我想按标记对它们进行分组 然后我想进一步将这些集合分组为同名学生 Map
  • 并发代码分析器

    我想知道是否有任何框架或应用程序 app 程序可以分析任何java代码的并发性 如果该工具知道 jre 提供的类和方法的所有实现 那么它就可以归结为对同步块和方法及其调用层次结构的简单分析 从这里它可以创建一个 Petri 网并确定地告诉您
  • 作为线程调用耗时的 JNI 任务

    我在从线程使用 JNI 调用本机函数时遇到了一个棘手的问题 本机函数是执行计算密集型任务的遗留代码 由于我不想冻结程序的其余部分 因此计算应该在后台线程中执行 EventBus https eventbus dev java net 用于将