`
zhangyu84849467
  • 浏览: 15426 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

sun.misc.Unsafe 操作数组(原创)

 
阅读更多

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

 

 

分享到:
评论

相关推荐

    JDK8中sun.misc下UnSafe类源代码 UnSafe.java

    5. **数组操作**:除了对对象字段的操作,UnSafe还可以直接操作数组,如`arrayBaseOffset`获取数组第一个元素相对于数组对象起始地址的偏移,`arrayIndexScale`获取数组元素大小。 四、风险与注意事项 尽管UnSafe...

    Java中的魔法类:sun.misc.Unsafe示例详解

    Java中的`sun.misc.Unsafe`类是一个特殊的存在,它提供了对Java语言规范之外的底层操作的访问。这个类主要用于优化性能和实现一些JVM级别的功能,但同时也因为其潜在的安全风险和不稳定因素,通常不推荐在常规编程中...

    mapdb-unsafe:提供使用 sun.misc.Unsafe 提高 10% 的内存存储

    `sun.misc.Unsafe` 是一个非常底层的 API,它允许 Java 程序员执行一些通常被认为是不安全或者不推荐的操作,如直接内存访问和对象字段的非反射操作。然而,这种使用方式被标记为过时,并且在 MapDB 2.0 及以后的...

    gate-core-8.0.zip

    在Java编程领域,`sun.misc.Unsafe`是一个神秘而强大的工具类,它提供了对Java内存模型的直接访问,包括堆外内存操作和字节数组的高效处理。`gate-core-8.0.zip`与`unsafe-tools.zip`的结合,为我们揭示了如何利用`...

    openjdk8 源码

    1. `sun.misc.Unsafe`: 这个类是Java中的一个神器,它提供了一系列底层操作,包括内存访问、对象布局、原子操作等。`Unsafe`绕过了Java的类型安全检查,可以直接操作内存,因此在高性能编程和框架设计中有着广泛的...

    一篇看懂Java中的Unsafe类

    Java中的`Unsafe`类是一个非常特殊的工具类,它位于`sun.misc`包下,不属于Java标准库的一部分。尽管如此,由于其强大的底层操作能力,它在许多高性能的Java框架和库中扮演着重要角色,例如Netty、Hadoop和Kafka。`...

    Java中内存分配的几种方法

    然而,对于需要底层控制的场景,Java也提供了一些低级别的API,如`sun.misc.Unsafe`,它允许开发者直接操作内存,类似于C语言中的指针操作。 1. **数组分配的上限** Java数组的大小受到`int`类型的限制,因为数组...

    JDK Unsafe 源码注释

    Unsafe类是Sun公司内部的一个类,它不是JDK标准API的一部分,而存在于sun.misc包中。虽然Oracle发行的JDK版本不包含Unsafe的源代码,但在并发编程中,Unsafe类为java.util.concurrent包里的类提供了底层支持,例如...

    Java并发编程-并发容器1

    在ConcurrentHashMap中,通过sun.misc.Unsafe类提供的底层内存操作来实现CAS,保证并发操作的原子性。 **扩容机制** 当ConcurrentHashMap中的元素数量超过加载因子(默认0.75)与当前容量的乘积时,将触发扩容。扩...

    Java Unsafe类1

    这个类在`sun.misc`包下,由于其潜在的危险性和不稳定性,官方并不推荐直接使用,甚至在Java 9之后有计划移除部分功能。然而,`Unsafe`的存在使得Java能够执行一些低级别的操作,比如直接操作内存、字段偏移量计算、...

    JAVA-提高反射效率

    6. **使用`sun.misc.Unsafe`**:`sun.misc.Unsafe`提供了直接访问内存的能力,可以绕过JVM的一些安全检查和额外的内存分配,从而提高性能。但这属于Oracle JDK的非公开API,使用需谨慎,因为它可能在未来的JDK版本中...

    深入分析Java并发编程之CAS

    在Java中,CAS操作是通过`Unsafe`类实现的,这个类位于`sun.misc`包下,提供了对内存的直接访问和原子操作。 `Unsafe`类是一个非常强大的工具,但同时也非常危险,因为它允许程序员绕过Java的内存安全机制,直接...

    Java面试.docx

    - CAS在Java中通过`sun.misc.Unsafe`类的原语方法实现,这些方法是native的,直接与硬件交互。 - CAS的缺点包括循环时间长、只能保证单个共享变量的原子操作,以及可能出现ABA问题。 5. **ABA问题**: - 当一个...

    JDK1.8源码,包含sun包,org包等,完整的源码

    例如,`sun.misc.Unsafe`是一个强大的类,允许直接内存访问和一些底层操作,虽然不推荐直接使用,但在某些高性能或低级别的编程中,它的存在极其有价值。 4. **Lambda表达式和函数式编程**:JDK 1.8引入了重大特性...

    Java-并发容器之ConcurrentHashMap

    此外,`sun.misc.Unsafe`类在ConcurrentHashMap的实现中扮演重要角色,其提供的原子操作方法(如compareAndSwap*)利用CAS算法确保线程安全,这种方法在没有竞争的情况下效率极高,即使发生冲突,重试次数也是有限的...

    后台篇jxy定制版.pdf

    在Java编程语言中,Unsafe是一个特殊的类,它位于Java的标准类库之外,位于sun.misc包下。由于这个类的特殊性质,它没有被正式列入Java官方文档,但它提供了对Java虚拟机中底层操作的直接访问,允许开发者执行一些低...

    Java界面版 内存地址转换的三种方式过程演示

    Java使用垃圾回收机制自动管理内存,但仍然可以通过`sun.misc.Unsafe`类间接获取对象的内存地址。这个类不是公开API,但有时会被用来进行高性能的编程。 1. **直接内存访问(Direct Memory Access)** Java中的NIO...

    java获取Max地址

    然而,如果你在编写底层的JNI(Java Native Interface)代码或者使用Java的`sun.misc.Unsafe`类,你可能会接触到内存地址的概念。`Unsafe`类提供了获取对象内存地址的方法,但请注意,这属于非公开API,使用时需谨慎...

    trove:Trove 3库的修补版本-更改Collections语义以匹配适当的java.util.Map语义

    宝库3.0.3 Trove库的修补版本-更改Collections语义以匹配适当的java.util.Map语义Palantir... 分支由Palantir Gotham 4.x使用: 此版本添加了数组,列表,集合和映射的实现,这些实现利用了sun.misc.Unsafe类分配的堆外

    jdk-7u45-windows-i586

    9. **堆外内存访问**:通过`sun.misc.Unsafe`类,开发者可以访问和操作Java堆之外的内存,这对于高性能和低级别的内存管理很有用。 10. **改进的编译器**:Javac编译器在Java 7中得到了优化,能更快地编译代码,...

Global site tag (gtag.js) - Google Analytics