sun.misc.Unsafe 操作数组的例子, 参照 jdk 的 java.util.concurrent.ConcurrentHashMap的源代码
package org.fantasy.unsafe; public interface Array<T> { /** * 根据下标获取指定的元素 * @param index * @return */ public T getObject(int index); /** * 根据下标修改指定的元素 * @param index * @param element * @return */ public boolean setObject(int index, T element); /** * 添加元素 * @param element * @return */ public boolean addObject(T element); /** * 删除元素 * @param element * @return */ public T remove(T element); /** * 根据下标删除元素 * @param index * @return */ public boolean remove(int index); }
package org.fantasy.unsafe; import java.lang.reflect.Field; import java.util.Arrays; import sun.misc.Unsafe; public class ArrayUnsafe<T> implements Array<T> { private static final int DEFAULT_INITIAL_CAPACITY = 10; private transient volatile Object[] elements; private volatile int size = 0; private static final Unsafe UNSAFE; private static final long ARRAY_OFFSET; private static final int ARRAY_SHIFT; private static final int INDEX_SCALE; private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private static final long SIZE_OFFSET; static { try { Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); unsafeField.setAccessible(true); UNSAFE = (Unsafe)unsafeField.get(null); ARRAY_OFFSET = UNSAFE.arrayBaseOffset(Object[].class); INDEX_SCALE = UNSAFE.arrayIndexScale(Object[].class); ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(INDEX_SCALE); SIZE_OFFSET = UNSAFE.objectFieldOffset(ArrayUnsafe.class.getDeclaredField("size")); } catch (Exception e) { throw new Error(e); } } public ArrayUnsafe() { this(DEFAULT_INITIAL_CAPACITY); } public ArrayUnsafe(int initialCapacity) { this.elements = new Object[initialCapacity]; } public T getObject(int index) { return (T)UNSAFE.getObjectVolatile(elements, getIndexScale(index)); } public boolean setObject(int index, T element) { rangeCheck(index); T oldElement = getObject(index); UNSAFE.putOrderedObject(elements, getIndexScale(index), element); if(oldElement != null && element == null) { int numMoved = size - index - 1; if(numMoved > 0) { System.arraycopy(elements, index + 1, elements, index, numMoved); } UNSAFE.compareAndSwapInt(this, SIZE_OFFSET, size, size - 1); UNSAFE.putOrderedObject(elements, getIndexScale(size), null); } return true; } private long getIndexScale(long index) { return (index << ARRAY_SHIFT) + ARRAY_OFFSET; } private void ensureCapacityInternal(int minCapacity) { if(minCapacity - elements.length > 0) grow(minCapacity); } private void grow(int minCapacity) { int oldCapacity = elements.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if(newCapacity - minCapacity < 0) newCapacity = minCapacity; if(newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elements = Arrays.copyOf(elements, newCapacity); } private static int hugeCapacity(int minCapacity) { if(minCapacity < 0) throw new OutOfMemoryError(); return minCapacity > MAX_ARRAY_SIZE ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } public boolean addObject(T element) { ensureCapacityInternal(size + 1); UNSAFE.putOrderedObject(elements, getIndexScale(size), element); UNSAFE.compareAndSwapInt(this, SIZE_OFFSET, size, size + 1); return true; } private void rangeCheck(int index) { if(index >= size || index < 0) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } } public T remove(T element) { for(int i = 0; i < elements.length; i++) { int index = i; T e = getObject(index); if(e != null) { if(e.equals(element)) { setObject(index, null); return e; } } } return null; } public boolean remove(int index) { rangeCheck(index); T removedElement = getObject(index); if(removedElement != null) return setObject(index, null); return false; } public static void main(String[] args) { Array<String> strArray = new ArrayUnsafe<String>(); for(int i = 0; i < 10; i++) { strArray.addObject(String.valueOf(i)); } strArray.addObject("hello"); strArray.addObject("world"); String s0 = strArray.getObject(0);// get "0" String s2 = strArray.getObject(2);// get "2" strArray.setObject(1, null); String s6 = strArray.remove("6"); // remove "6" String sNull = strArray.remove("foo");// null boolean result = strArray.remove(9); } }
相关推荐
5. **数组操作**:除了对对象字段的操作,UnSafe还可以直接操作数组,如`arrayBaseOffset`获取数组第一个元素相对于数组对象起始地址的偏移,`arrayIndexScale`获取数组元素大小。 四、风险与注意事项 尽管UnSafe...
Java中的`sun.misc.Unsafe`类是一个特殊的存在,它提供了对Java语言规范之外的底层操作的访问。这个类主要用于优化性能和实现一些JVM级别的功能,但同时也因为其潜在的安全风险和不稳定因素,通常不推荐在常规编程中...
`sun.misc.Unsafe` 是一个非常底层的 API,它允许 Java 程序员执行一些通常被认为是不安全或者不推荐的操作,如直接内存访问和对象字段的非反射操作。然而,这种使用方式被标记为过时,并且在 MapDB 2.0 及以后的...
在Java编程领域,`sun.misc.Unsafe`是一个神秘而强大的工具类,它提供了对Java内存模型的直接访问,包括堆外内存操作和字节数组的高效处理。`gate-core-8.0.zip`与`unsafe-tools.zip`的结合,为我们揭示了如何利用`...
1. `sun.misc.Unsafe`: 这个类是Java中的一个神器,它提供了一系列底层操作,包括内存访问、对象布局、原子操作等。`Unsafe`绕过了Java的类型安全检查,可以直接操作内存,因此在高性能编程和框架设计中有着广泛的...
Java中的`Unsafe`类是一个非常特殊的工具类,它位于`sun.misc`包下,不属于Java标准库的一部分。尽管如此,由于其强大的底层操作能力,它在许多高性能的Java框架和库中扮演着重要角色,例如Netty、Hadoop和Kafka。`...
然而,对于需要底层控制的场景,Java也提供了一些低级别的API,如`sun.misc.Unsafe`,它允许开发者直接操作内存,类似于C语言中的指针操作。 1. **数组分配的上限** Java数组的大小受到`int`类型的限制,因为数组...
Unsafe类是Sun公司内部的一个类,它不是JDK标准API的一部分,而存在于sun.misc包中。虽然Oracle发行的JDK版本不包含Unsafe的源代码,但在并发编程中,Unsafe类为java.util.concurrent包里的类提供了底层支持,例如...
在ConcurrentHashMap中,通过sun.misc.Unsafe类提供的底层内存操作来实现CAS,保证并发操作的原子性。 **扩容机制** 当ConcurrentHashMap中的元素数量超过加载因子(默认0.75)与当前容量的乘积时,将触发扩容。扩...
这个类在`sun.misc`包下,由于其潜在的危险性和不稳定性,官方并不推荐直接使用,甚至在Java 9之后有计划移除部分功能。然而,`Unsafe`的存在使得Java能够执行一些低级别的操作,比如直接操作内存、字段偏移量计算、...
6. **使用`sun.misc.Unsafe`**:`sun.misc.Unsafe`提供了直接访问内存的能力,可以绕过JVM的一些安全检查和额外的内存分配,从而提高性能。但这属于Oracle JDK的非公开API,使用需谨慎,因为它可能在未来的JDK版本中...
在Java中,CAS操作是通过`Unsafe`类实现的,这个类位于`sun.misc`包下,提供了对内存的直接访问和原子操作。 `Unsafe`类是一个非常强大的工具,但同时也非常危险,因为它允许程序员绕过Java的内存安全机制,直接...
- CAS在Java中通过`sun.misc.Unsafe`类的原语方法实现,这些方法是native的,直接与硬件交互。 - CAS的缺点包括循环时间长、只能保证单个共享变量的原子操作,以及可能出现ABA问题。 5. **ABA问题**: - 当一个...
例如,`sun.misc.Unsafe`是一个强大的类,允许直接内存访问和一些底层操作,虽然不推荐直接使用,但在某些高性能或低级别的编程中,它的存在极其有价值。 4. **Lambda表达式和函数式编程**:JDK 1.8引入了重大特性...
此外,`sun.misc.Unsafe`类在ConcurrentHashMap的实现中扮演重要角色,其提供的原子操作方法(如compareAndSwap*)利用CAS算法确保线程安全,这种方法在没有竞争的情况下效率极高,即使发生冲突,重试次数也是有限的...
在Java编程语言中,Unsafe是一个特殊的类,它位于Java的标准类库之外,位于sun.misc包下。由于这个类的特殊性质,它没有被正式列入Java官方文档,但它提供了对Java虚拟机中底层操作的直接访问,允许开发者执行一些低...
Java使用垃圾回收机制自动管理内存,但仍然可以通过`sun.misc.Unsafe`类间接获取对象的内存地址。这个类不是公开API,但有时会被用来进行高性能的编程。 1. **直接内存访问(Direct Memory Access)** Java中的NIO...
然而,如果你在编写底层的JNI(Java Native Interface)代码或者使用Java的`sun.misc.Unsafe`类,你可能会接触到内存地址的概念。`Unsafe`类提供了获取对象内存地址的方法,但请注意,这属于非公开API,使用时需谨慎...
宝库3.0.3 Trove库的修补版本-更改Collections语义以匹配适当的java.util.Map语义Palantir... 分支由Palantir Gotham 4.x使用: 此版本添加了数组,列表,集合和映射的实现,这些实现利用了sun.misc.Unsafe类分配的堆外
9. **堆外内存访问**:通过`sun.misc.Unsafe`类,开发者可以访问和操作Java堆之外的内存,这对于高性能和低级别的内存管理很有用。 10. **改进的编译器**:Javac编译器在Java 7中得到了优化,能更快地编译代码,...