gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 22:38:30 24 4
gpt4 key购买 nike

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

native 函数是执行计算密集型任务的遗留代码。由于我不想卡住程序的其余部分,因此计算应在后台线程中执行。 EventBus用于将计算结果发送回主程序。

基本上它应该很简单,像这样:

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方法,它只是构造一个后台线程来做同样的事情,当它被连续调用时会导致 native 代码中的各种崩溃。连续我的意思是只有在前一个线程完成并返回结果后才会再次调用它。注意 native 代码标记为 synchronized以确保一次只能运行一个实例。

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

感谢您的任何提示!

最佳答案

在谷歌搜索并找到短语 "I've found JNI to be very buggy when called from seperate threads... So make sure only one thread ever calls your native code!" 后,我想出了一个可行的解决方案。 .这似乎是真的;解决方案是保持一个持久的、“可重用的”线程 - 我使用了 Executors.newSingleThreadExecutor() - 并且仅从该线程调用 native 代码。有用。

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

无论是 JNI 错误, native 代码中的错误,它们与操作系统之间的交互中的某些问题,还是其他什么,都将很有趣。但有时您只是没有机会详细调试 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);
}

关于multithreading - 作为线程调用耗时的JNI任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1157836/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com