有人可以解释以下代码吗?

亚伦
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);
        }
    }
}

此示例显示“线程安全访问直接内存”,它用于在进程之间共享数据。在两个程序中运行时,一个带有奇数,另一个带有偶数。您会看到每个进程都通过持久共享内存来更改数据。

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

  1. tmp文件是用来做什么的?
  2. UnSafe在这里做什么?
  3. 为什么在这里不安全使用;
  4. 为什么将字段强制转换为UnSafe类型,而不是sun.misc.Unsafe.getUnsafe()?
斯蒂芬·C

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

tmp文件用于做什么

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

UnSafe在这里做什么?

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

address读取屏障读取64位即确保它正在从主内存(而不是高速缓存)中读取

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

执行原子比较和交换。如果at的值addressvalue,则原子地将其更改为value + 1

为什么在这里不安全使用;

因为这是一种好方法,所以请执行1个低级操作(精确地使用那些语义。(例如Java基本互斥体,并且Lock当使用它们的线程处于单独的进程中时则没有指定“ Java内存模型”语义)。

为什么将字段强制转换为UnSafe类型,而不是sun.misc.Unsafe.getUnsafe()?

这是一些讨厌的东西,旨在解决JVM的限制。如果您只是打电话给Unsafe.getUnsafe()您,通常会得到一个SecurityException

参考:

换个角度看.....


1-可能是编写不可移植的本机代码的唯一途径。但是请记住,Unsafe该类是为JVM内部使用而设计的,API和行为可能会更改,恕不另行通知。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

有人可以向我解释以下代码吗?

有人可以解释以下 R 代码片段吗?

有人可以解释以下代码的功能pop(更具体地说是retval变量)吗?

有人可以解释我如何为以下代码编写junit测试代码?

有人可以帮助我更正以下代码吗?

有人可以帮我理解以下代码块吗?

有人可以详细说明以下代码吗?

有人可以用javascript解释以下代码吗?它用于读取文本文件,但是我不了解XML和AJAX的内容?

有人可以解释如何使用str.index和str.find以及以下代码为何错误

有人可以向我解释以下Java代码在做什么吗?

有人可以解释一下以下Java递归代码段吗?

有人可以解释以下javascript代码的最后输出结果吗?

有人可以解释以下pytorch神经网络中的层代码吗

有人可以解释以下awk脚本的含义吗?

有人可以解释以下Ruby on Rails错误吗?

有人可以解释以下语法及其功能吗?

有人可以解释以下C ++语法吗?

有人可以解释此代码的工作原理吗?

有人可以解释这个 C++ 代码吗?

移位:有人可以解释这段代码的作用吗?

有人可以解释这些C代码吗?

有人可以为我解释这段代码吗

有人可以解释此代码的工作原理吗?

有人可以解释这些代码行的含义吗?

有人可以解释这段代码的作用吗?

有人可以向我解释这段代码吗

有人可以解释我这段代码吗?

有人可以解释这个python代码的作用吗?

有人可以帮助我了解以下代码