gpt4 book ai didi

java - 有人可以解释一下代码吗?

转载 作者:行者123 更新时间:2023-11-30 02:05:07 25 4
gpt4 key购买 nike

import sun.misc.Unsafe;
import sun.nio.ch.DirectBuffer;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Field;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class PingPongMapMain {
public static void main(String... args) throws IOException {
boolean odd;
switch (args.length < 1 ? "usage" : args[0].toLowerCase()) {
case "odd":
odd = true;
break;
case "even":
odd = false;
break;
default:
System.err.println("Usage: java PingPongMain [odd|even]");
return;
}
int runs = 10000000;
long start = 0;
System.out.println("Waiting for the other odd/even");
File counters = new File(System.getProperty("java.io.tmpdir"),"counters.deleteme");
counters.deleteOnExit();
try (FileChannel fc = new RandomAccessFile(counters, "rw").getChannel()) {
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
long address = ((DirectBuffer) mbb).address();
for (int i = -1; i < runs; i++) {
for (; ; ) {
long value = UNSAFE.getLongVolatile(null, address);
boolean isOdd = (value & 1) != 0;
if (isOdd != odd)
// wait for the other side.
continue;
// make the change atomic, just in case there is more than one odd/even process
if (UNSAFE.compareAndSwapLong(null, address, value, value + 1))
break;
}
if (i == 0) {
System.out.println("Started");
start = System.nanoTime();
}
}
}
System.out.printf("... Finished, average ping/pong took %,d ns%n",
(System.nanoTime() - start) / runs);
}

static final Unsafe UNSAFE;
static {
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
UNSAFE = (Unsafe) theUnsafe.get(null);
} catch (Exception e) {
throw new AssertionError(e);
}
}
}

This example shows "Thread safe access to direct memory", and it used for share data between processes.When run this in two programs, one with odd and the other with even. you can see that each process is changing data via persisted shared memory.

但我对一些事情感到困惑:

  1. tmp 文件的用途是什么;
  2. UnSafe 在这里有什么用;
  3. 为什么在这里使用不安全;
  4. 为什么将字段转换为 UnSafe 类型而不是 sun.misc.Unsafe.getUnsafe()?

最佳答案

该程序说明了两个独立的 Java 进程如何通过通过内存映射文件实现的共享内存段进行通信。一个进程将共享段中某个位置的数字设为奇数,另一个进程将其设为偶数……反复……在两个进程之间“乒乓球”。

what does the tmp file used for

它有效地为两个进程共享内存段提供了一种方法。创建一个文件,并将其映射到两个进程的地址空间。最终结果是两个进程共享相同的内存区域。

what does UnSafe used for here;

    long value = UNSAFE.getLongVolatile(null, address);

使用读屏障从地址读取64位;即确保它从主内存(而不是缓存内存)读取

    UNSAFE.compareAndSwapLong(null, address, value, value + 1));

执行原子比较和交换。如果 address 处的值为 value,则自动将其更改为 value + 1

why unsafe use here;

因为这是执行这些低级操作的好方法1(正是具有这些语义。(像 Java 原始互斥体和 Lock 这样的东西没有指定“当使用它们的线程位于单独的进程中时,Java 内存模型”语义。)

why cast a field to a UnSafe type but not sun.misc.Unsafe.getUnsafe()?

这是一些旨在绕过 JVM 限制的令人讨厌的东西。如果您只是调用 Unsafe.getUnsafe(),您通常会收到 SecurityException

引用:

只要看向别处......

<小时/>

1 - 可能是除了编写不可移植的 native 代码之外的唯一方法。但请记住,Unsafe 类是为 JVM 内部使用而设计的,API 和行为可能发生更改,恕不另行通知。

关于java - 有人可以解释一下代码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51611204/

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