Unsafe considered Awesome!

I’ve been planning on playing with sun.misc.Unsafe for a while now but couldn’t find the time.

Long story short… Unsafe is awesome.

Check out the cool things you can do with it (that you normally couldn’t do with Java):



/**
    * Allocates a new block of native memory, of the given size in bytes.  The
    * contents of the memory are uninitialized; they will generally be
    * garbage.  The resulting native pointer will never be zero, and will be
    * aligned for all value types.  Dispose of this memory by calling {@link
    * #freeMemory}, or resize it with {@link #reallocateMemory}.
    *
    * @throws IllegalArgumentException if the size is negative or too large
    *         for the native size_t type
    *
    * @throws OutOfMemoryError if the allocation is refused by the system
    *
    * @see #getByte(long)
    * @see #putByte(long, byte)
    */
   public native long allocateMemory(long bytes);

    /**
    * Sets all bytes in a given block of memory to a fixed value
    * (usually zero).
    *
    * <p>This method determines a block's base address by means of two parameters,
    * and so it provides (in effect) a <em>double-register</em> addressing mode,
    * as discussed in {@link #getInt(Object,long)}.  When the object reference is null,
    * the offset supplies an absolute base address.
    *
    * <p>The stores are in coherent (atomic) units of a size determined
    * by the address and length parameters.  If the effective address and
    * length are all even modulo 8, the stores take place in 'long' units.
    * If the effective address and length are (resp.) even modulo 4 or 2,
    * the stores take place in units of 'int' or 'short'.
    *
    * @since 1.7
    */
   public native void setMemory(Object o, long offset, long bytes, byte value);

   /**
    * Sets all bytes in a given block of memory to a copy of another
    * block.
    *
    * <p>This method determines each block's base address by means of two parameters,
    * and so it provides (in effect) a <em>double-register</em> addressing mode,
    * as discussed in {@link #getInt(Object,long)}.  When the object reference is null,
    * the offset supplies an absolute base address.
    *
    * <p>The transfers are in coherent (atomic) units of a size determined
    * by the address and length parameters.  If the effective addresses and
    * length are all even modulo 8, the transfer takes place in 'long' units.
    * If the effective addresses and length are (resp.) even modulo 4 or 2,
    * the transfer takes place in units of 'int' or 'short'.
    *
    * @since 1.7
    */
   public native void copyMemory(Object srcBase, long srcOffset,
                                 Object destBase, long destOffset,
                                 long bytes);
    /**
    * Report the size in bytes of a native pointer, as stored via {@link
    * #putAddress}.  This value will be either 4 or 8.  Note that the sizes of
    * other primitive types (as stored in native memory blocks) is determined
    * fully by their information content.
    */
   public native int addressSize();

   /** The value of {@code addressSize()} */
   public static final int ADDRESS_SIZE = theUnsafe.addressSize();

   /**
    * Report the size in bytes of a native memory page (whatever that is).
    * This value will always be a power of two.
    */
   public native int pageSize();
 must get unlocked via {@link #monitorExit}. */
   public native void monitorEnter(Object o);

   /**
    * Unlock the object.  It must have been locked via {@link
    * #monitorEnter}.
    */
   public native void monitorExit(Object o);

   /**
    * Tries to lock the object.  Returns true or false to indicate
    * whether the lock succeeded.  If it did, the object must be
    * unlocked via {@link #monitorExit}.
    */
   public native boolean tryMonitorEnter(Object o);

   /** Throw the exception without telling the verifier. */
   public native void throwException(Throwable ee);


   /**
    * Atomically update Java variable to <tt>x</tt> if it is currently
    * holding <tt>expected</tt>.
    * @return <tt>true</tt> if successful
    */
   public final native boolean compareAndSwapObject(Object o, long offset,
                                                    Object expected,
                                                    Object x);

   /**
    * Atomically update Java variable to <tt>x</tt> if it is currently
    * holding <tt>expected</tt>.
    * @return <tt>true</tt> if successful
    */
   public final native boolean compareAndSwapInt(Object o, long offset,
                                                 int expected,
                                                 int x);

   /**
    * Atomically update Java variable to <tt>x</tt> if it is currently
    * holding <tt>expected</tt>.
    * @return <tt>true</tt> if successful
    */
   public final native boolean compareAndSwapLong(Object o, long offset,
                                                  long expected,
                                                  long x);
    /**
    * Unblock the given thread blocked on <tt>park</tt>, or, if it is
    * not blocked, cause the subsequent call to <tt>park</tt> not to
    * block.  Note: this operation is "unsafe" solely because the
    * caller must somehow ensure that the thread has not been
    * destroyed. Nothing special is usually required to ensure this
    * when called from Java (in which there will ordinarily be a live
    * reference to the thread) but this is not nearly-automatically
    * so when calling from native code.
    * @param thread the thread to unpark.
    *
    */
   public native void unpark(Object thread);

   /**
    * Block current thread, returning when a balancing
    * <tt>unpark</tt> occurs, or a balancing <tt>unpark</tt> has
    * already occurred, or the thread is interrupted, or, if not
    * absolute and time is not zero, the given time nanoseconds have
    * elapsed, or if absolute, the given deadline in milliseconds
    * since Epoch has passed, or spuriously (i.e., returning for no
    * "reason"). Note: This operation is in the Unsafe class only
    * because <tt>unpark</tt> is, so it would be strange to place it
    * elsewhere.
    */
   public native void park(boolean isAbsolute, long time);
    /**
    * Gets the load average in the system run queue assigned
    * to the available processors averaged over various periods of time.
    * This method retrieves the given <tt>nelem</tt> samples and
    * assigns to the elements of the given <tt>loadavg</tt> array.
    * The system imposes a maximum of 3 samples, representing
    * averages over the last 1,  5,  and  15 minutes, respectively.
    *
    * @params loadavg an array of double of size nelems
    * @params nelems the number of samples to be retrieved and
    *         must be 1 to 3.
    *
    * @return the number of samples actually retrieved; or -1
    *         if the load average is unobtainable.
    */
   public native int getLoadAverage(double[] loadavg, int nelems);



%d bloggers like this: