一段C/C++代码可以为JNI方法提供一个函数指针数组.但是有没有办法直接从Java代码内部(不使用JNI或类似代码)调用数组指针指向的函数?JNI以某种方式做了类似的事情,所以必须有办法.JNI是如何做到的?是通过sun.misc.Unsafe吗?即使不是,我们是否可以使用一些不安全的解决方法来获取执行此操作的JVM代码?
我当然不打算在商业上使用它.我甚至不是专业人士,我只是非常喜欢编码而且我最近一直在研究CUDA所以我想也许我可以尝试将所有东西混合在一起,但JNI调用的开销会破坏GPU加速代码的目的.
因此,在接受一些求职面试之后,我想编写一个小程序来检查i++ java中的非原子性,并且在实践中应该添加一些锁定来保护它.原来你应该,但这不是问题.
所以我在这里写这个程序只是为了检查它.
事情是,它挂起了.似乎主线程被挂t1.join()
在线上,即使两个工作线程都应该因为stop = true前一行而完成.
我发现悬挂停止如果:
boolean stop为volatile,导致写入立即被工作线程看到,或者t为volatile...为此,我不知道是什么导致了不挂.有人可以解释发生了什么吗?为什么我会看到悬挂,为什么它会在这三种情况下停止?
public class Test {
static /* volatile */ long t = 0;
static long[] counters = new long[2];
static /* volatile */ boolean stop = false;
static Object o = new Object();
public static void main(String[] args)
{
Thread t1 = createThread(0);
Thread t2 = createThread(1);
t1.start();
t2.start();
Thread.sleep(1000);
stop = true;
t1.join();
t2.join();
System.out.println("counter …Run Code Online (Sandbox Code Playgroud) 我试图演示一个"随时算法" - 一种可以随时停止并返回其当前结果的算法.演示算法只返回i的一些数学函数,其中i正在增加.它会查看它是否被中断,如果是,则返回当前值:
static int algorithm(int n) {
int bestSoFar = 0;
for (int i=0; i<n; ++i) {
if (Thread.interrupted())
break;
bestSoFar = (int)Math.pow(i, 0.3);
}
return bestSoFar;
}
Run Code Online (Sandbox Code Playgroud)
在主程序中,我使用它像这样:
Runnable task = () -> {
Instant start = Instant.now();
int bestSoFar = algorithm(1000000000);
double durationInMillis = Duration.between(start, Instant.now()).toMillis();
System.out.println("after "+durationInMillis+" ms, the result is "+bestSoFar);
};
Thread t = new Thread(task);
t.start();
Thread.sleep(1);
t.interrupt();
t = new Thread(task);
t.start();
Thread.sleep(10);
t.interrupt();
t = new Thread(task);
t.start();
Thread.sleep(100);
t.interrupt();
t …Run Code Online (Sandbox Code Playgroud) 我想比较的性能pow(x,2.0)和pow(x,2.0000001)和我,虽然那2.0会快很多,但都是以相同的速度.我甚至通过运行带-Xint参数的jar来删除JIT优化.
知道为什么会这样吗,拜托?非常感谢!
我写了一个小的静态JNI函数,它只有5个指令长.JVM是否可以将此代码内联到一个经常调用它的方法体中,或者它总是call在JITed方法中生成一条指令?
例如:
public class SomeClass {
private static native long func();
public void doLoop() {
for(int i = 0; i < 0xFFFFFF; i++) {
func();
}
}
public static void main(String[] args) {
for(int i = 0; i < 0xFFFFFF; i++) {
doLoop();
}
}
}
Run Code Online (Sandbox Code Playgroud)
是否有可能为JVM内联的代码func进入doLoop,否则将只是其编译为call func
如果您想要加载一个类的多个版本,如果它们实现了共享接口并且位于单独的 JAR 中,则可以为每个版本使用单独的类加载器来执行此操作。
如果您有一个调用本机代码的 JAR,则可以将本机代码的共享库 (DLL) 存储在其 JAR 中,方法是将共享库提取到临时文件,然后使用System.load从临时文件加载该库。
但如果两者都做,会有效吗?如果两个版本的 JAR 都调用本机代码,并且都包含不同版本的共享库,会发生什么情况?
让我们假设两个 JAR 使用不同的临时文件来存储共享库的副本。但是共享库的两个版本都具有调用具有相同声明的本机 (C) 函数的本机代码(但这些函数的实现不同)。JVM/类加载器/会将System.load Java 代码委托给正确的本机代码吗?或者 JVM 会抱怨名称冲突吗?
如果该方案确实失败,我如何使用使用本机代码的类的多个版本?