How and why Unsafe was used in Java---reference

Source: Internet
Author: User

by Peter Lawrey

https://www.voxxed.com/blog/2014/12/how-and-why-unsafe-is-used-in-java/

Overview

Sun.misc.Unsafe have been in Java from at least as far back as Java 1.4 (2004). In Java 9, Unsafe would be is hidden along with many other, for-internal-use classes.  To improve the maintainability of the JVM. While it's still unclear exactly what would replace Unsafe, and I suspect it'll be more than one thing which replaces it , it raises the question, why are it used at all?

Doing things which the Java language doesn ' t allow but is still useful.

Java doesn ' t allow many of the tricks which is available to lower level languages. For the most developers this is very good thing, and it isn't only saves if yourself, it also saves you from your Co-worke  Rs.  It also makes it easier to import open source code because you know there are limits to how much damage they can do. Or at least there are limits to how much you can do accidentally. If You try hard enough you can still do damage.

But what would you even try, are you might wonder? When building libraries many (but not all) of the methods in Unsafe be useful and in some cases, there was no other Do the same thing without using JNI, which are even more dangerous and you lose the "compile once, run anywhere"

Deserialization of Objectswhen deserializing or building an object using a framework, you make the assumption you want to  Reconstitute an object which existed before. You expect this reflection to either call the setters of the class, or more likely set the internal fields di  rectly, even the final fields. The problem is your want to create an instance of an object, but you don ' t really need a constructor as this is likely to O Nly make things more difficult and has side effects.
1234567891011 public class A implements Serializable {    private final int num;    public A(int num) {        System.out.println("Hello Mum");        this.num = num;    }    public int getNum() {        return num;    }}

In this class, you should is able to rebuild and set the final field, but if you have a constructor and it might D  o things which don ' t has anything to does with deserialization. For these reasons many libraries use Unsafe to create instances without calling a constructor

123 Unsafe unsafe = getUnsafe();Class aClass = A.class;A a = (A) unsafe.allocateInstance(aClass);

Calling Allocateinstance avoids the need to call the appropriate constructor, when we don ' t need one.

Thread safe access to direct memory

Another use for Unsafe are thread safe access to off heap memory.  Bytebuffer gives you safe access to off heap or direct memory, however it doesn ' t has any thread safe operations. This is particularly useful if your want to share data between processes.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 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);        }    }}

When you run this in both programs, one with odd and the other with even. You can see, each of the process is changing data via persisted shared memory.

In each program it maps the same is of the disks cache into the process.  There is actually only one copy of the file in memory. This means the memory can is shared, provided you use the thread safe operations such as the volatile and CAS operations.

The output on a i7-3970x is

Waiting for the other Odd/even
Started
... Finished, average Ping/pong took-NS

That's the round NS, the trip time between, and the processes. When you consider System V IPC takes around 2,500 NS and IPC volatile instead of persisted, which is pretty quick.

is using the Unsafe suitable for work?  I wouldn ' t recommend you use Unsafe directly.  It requires far more testing than natural Java development.  For the reason I suggest you use a library where it's usage has been tested already.  If you wan to use the Unsafe yourself, I suggest you thoughly test it's usage in a stand alone library. This limits how unsafe are used in your application and give syou a safer, unsafe.conclusionit are interesting that Unsafe E  Xists in Java, and your might to play with it at home. It has some work applications especially in writing low level libraries, but in general it's better to use a library whic H uses Unsafe which have been tested than use it directly yourself.

How and why Unsafe was used in Java---reference

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.