All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rpc.turbo.util.concurrent.ConcurrentArrayList Maven / Gradle / Ivy

There is a newer version: 0.0.9
Show newest version
package rpc.turbo.util.concurrent;

import static rpc.turbo.util.UnsafeUtils.unsafe;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
import java.util.RandomAccess;

/**
 * only support add get set, not support remove
 * 
 * @author Hank
 *
 * @param 
 */
public class ConcurrentArrayList implements RandomAccess {
	public static final int MAXIMUM_CAPACITY = 1 << 30;

	private static final long SIZE_OFFSET;

	private volatile Object[] values;
	private volatile int size;// unsafe atomic operate

	public ConcurrentArrayList() {
		this(16);
	}

	public ConcurrentArrayList(int initialCapacity) {
		if (initialCapacity < 2) {
			throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity);
		}

		if (initialCapacity > MAXIMUM_CAPACITY) {
			throw new IndexOutOfBoundsException("Illegal initial capacity: " + initialCapacity);
		}

		ensureCapacity(initialCapacity);
	}

	public void add(T value) {
		int index = insertIndex();
		values[index] = value;
	}

	public void addAll(Collection collection) {
		if (collection == null) {
			return;
		}

		ensureCapacity(size + collection.size());

		for (T t : collection) {
			add(t);
		}
	}

	@SuppressWarnings("unchecked")
	public T get(int index) {
		Objects.checkIndex(index, size);
		return (T) values[index];
	}

	public void set(int index, T value) {
		Objects.checkIndex(index, size);
		values[index] = value;
	}

	public int size() {
		return size;
	}

	public void clear() {
		size = 0;
	}

	@SuppressWarnings("unchecked")
	public ArrayList toArrayList() {
		int finalSize = size;
		Object[] finalValues = values;

		ArrayList list = new ArrayList<>(finalSize);

		for (int i = 0; i < finalSize; i++) {
			list.add((T) finalValues[i]);
		}

		return list;
	}

	private int insertIndex() {
		int index = unsafe().getAndAddInt(this, SIZE_OFFSET, 1);
		ensureCapacity(index + 1);

		return index;
	}

	private void ensureCapacity(int capacity) {
		Object[] theArray = values;
		if (theArray != null && theArray.length >= capacity) {
			return;
		}

		synchronized (this) {
			Object[] finalArray = values;
			if (finalArray != null && finalArray.length >= capacity) {
				return;
			}

			int newCapacity = tableSizeFor(capacity);

			if (newCapacity > MAXIMUM_CAPACITY) {
				throw new IndexOutOfBoundsException(newCapacity);
			}

			Object[] objs = new Object[newCapacity];

			if (finalArray != null) {
				System.arraycopy(finalArray, 0, objs, 0, finalArray.length);
			}

			values = objs;
		}
	}

	private static final int tableSizeFor(int cap) {
		int n = cap - 1;
		n |= n >>> 1;
		n |= n >>> 2;
		n |= n >>> 4;
		n |= n >>> 8;
		n |= n >>> 16;
		return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
	}

	static {
		try {
			Field field = ConcurrentArrayList.class.getDeclaredField("size");
			SIZE_OFFSET = unsafe().objectFieldOffset(field);
		} catch (Throwable e) {
			throw new Error(e);
		}
	}

	public static void main(String[] args) {
		ConcurrentArrayList list = new ConcurrentArrayList<>();

		for (int i = 0; i < 1024; i++) {
			list.add(i);
		}

		for (int i = 0; i < 1024; i++) {
			System.out.println(list.get(i));
		}

	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy