ThreadLocal看看

package ThreadLocalZXF;

import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;

import javax.validation.Valid;

import com.sun.jndi.url.iiopname.iiopnameURLContextFactory;

import ThreadLocalZXF.ThreadLocalZXF.ThreadLocalMap.Entry;
import WeakReferenceZXF.WeakReferenceZXF;

public class ThreadLocalZXF<T> {

	private final int threadLocalHashCode = nexHashCode();

	private static AtomicInteger nexHashCode = new AtomicInteger();

	/**
	 * def magic_hash(n): ... for i in range(n): ... nextHashCode = i *
	 * HASH_INCREMENT + HASH_INCREMENT ... print nextHashCode & (n - 1), ...
	 * print ... >>> magic_hash(16)
	 */
	private static final int HASH_INCREMENT = 0X61c88647;

	private static int nextHashCode() {
		return nexHashCode.getAndAdd(HASH_INCREMENT);
	}

	static class ThreadLocalMap {
		static class Entry extends WeakReferenceZXF<ThreadLocalZXF<?>> {

			Object value;

			public Entry(ThreadLocalZXF<?> k, Object v) {
				// threadlocal 弱引用
				super(k);
				value = v;

			}

		}

		private static final int INITIAL_CAPACITY = 16;

		private Entry[] table;

		private int size = 0;

		private int threshold;

		private void setThreshold(int len) {
			threshold = len * 2 / 3;
		}

		private static int nextIndex(int i, int len) {
			return ((i + 1 < len) ? i + 1 : 0);
		}

		private static int prevIndex(int i, int len) {
			return ((i - 1 >= 0) ? i - 1 : len - 1);
		}

		ThreadLocalMap(ThreadLocalZXF<?> firstKey, Object firstValue) {
			table = new Entry[INITIAL_CAPACITY];
			int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
			table[i] = new Entry(firstKey, firstValue);
			size = 1;
			setThreshold(INITIAL_CAPACITY);

		}

		private ThreadLocalMap(ThreadLocalMap parentMap) {
			Entry[] parentTable = parentMap.table;
			int len = parentTable.length;
			setThreshold(len);
			table = new Entry[len];

			for (int j = 0; j < len; j++) {
				Entry e = parentTable[j];
				if (e != null) {
					@SuppressWarnings("unchecked")
					ThreadLocalZXF<Object> key = (ThreadLocalZXF<Object>) e
							.get();
					if (key != null) {
						Object value = key.childValue(e.value);
						Entry c = new Entry(key, value);
						int h = key.threadLocalHashCode & (len - 1);
						while (table[h] != null) {
							h = nextIndex(h, len);
						}
						table[h] = c;
						size++;
					}
				}
			}
		}

		private Entry getEntry(ThreadLocalZXF<?> key) {
			int i = key.threadLocalHashCode & (table.length - 1);
			Entry e = table[i];
			if (e != null && e.get() == key) {
				return e;
			} else {
				return getEntryAfterMiss(key, i, e);
			}
		}

		private Entry getEntryAfterMiss(ThreadLocalZXF<?> key, int i, Entry e) {
			Entry[] tab = table;
			int len = tab.length;
			while (e != null) {
				ThreadLocalZXF<?> k = e.get();
				if (k == key)
					return e;
				if (k == null)
					// hash冲突
					// 存在弱引用被清理,entry=<null,vo>,清理完继续找,至少2个对象有着相同的hash
					expungeStaleEntry(i);
				else
					// hash冲突,
					i = nextIndex(i, len);
				e = tab[i];
			}
			return null;
		}

		private void set(ThreadLocalZXF<?> key, Object value) {
			Entry[] tab = table;
			int len = tab.length;
			int i = key.threadLocalHashCode & (len - 1);

			for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) {
				ThreadLocalZXF<?> k = e.get();

				if (k == key) {
					e.value = value;
					return;
				}
                //可能<null,VO> or hash碰撞,导致槽错位
				if (k == null) {
					replaceStaleEntry(key, value, i);
					return;
				}
			}

			tab[i] = new Entry(key, value);
			int sz = ++size;
			if (!cleanSomeSlots(i, size) && sz >= threshold) {
				rehash();
			}
		}
		
		/**
		 * 1.向下找,找到k符合,和slot位置的entry交换,如向上向下均未发现任何stale,如果清理该出slot(原k位置)
		 * 2.向下找,找到k符合,交换slot位置的entry,如向上有stale,则处理向上,否则,向下有stale,则出理向下
		 * 3.向下也没找到k,直接复制给slot位置
		 * 4.向下也没找到k,如向上有stale,则处理向上,否则,向下有stale,则出理向下,否则无
		 * @param key
		 * @param value
		 * @param staleSlot
		 */

		private void replaceStaleEntry(ThreadLocalZXF<?> key, Object value,
				int staleSlot) {
			Entry[] tab = table;
			int len = tab.length;
			Entry e;

			int slotToExpunge = staleSlot;
			
			//向上查找是不是有变质的
			for (int i = prevIndex(staleSlot, len); (e = tab[i]) != null; i = prevIndex(
					i, len)) {
				if (e.get() == null) {
					slotToExpunge = i;
				}
			}

			for (int i = nextIndex(staleSlot, len); (e = tab[i]) != null; i = nextIndex(
					i, len)) {
				ThreadLocalZXF<?> k = e.get();
                //原来想找的entry在这,赶紧和变质的sb,换回来,下次就可以直接通过hash找到你了
				if (k == key) {
					e.value = value;

					tab[i] = tab[staleSlot];
					tab[staleSlot] = e;
                    //避免误伤友军,staleSlot位置已被填充,此时如果再清expunge,将会清理正确数值
					if (slotToExpunge == staleSlot) {
						slotToExpunge = i;
					}
					cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
					return;
				}
				//往上找的没找到stale的,slotToExpunge记录向下找的第一个key==null的位置
				if(k==null&&slotToExpunge == staleSlot){
					slotToExpunge = i;
				}
			}
			//没找到相匹配的key,在stale槽插入新entry
			tab[staleSlot].value = null;
			tab[staleSlot] = new Entry(key, value);
			//存在其他stale的entry,清理!!!
			if(slotToExpunge != staleSlot){
				cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
			}

		}

	}

	protected T initialValue() {
		return null;
	}

	/**
	 * 反回当前线程的初始值
	 * 
	 * @param supplier
	 * @return
	 */
	public static <S> ThreadLocalZXF<S> withInitial(
			Supplier<? extends S> supplier) {
		return new SuppliedThreadLocal<>(supplier);
	}

	public T get(){
    	Thread t = Thread.currentThread();
    	Threadlo
    }
}

猜你喜欢

转载自blog.csdn.net/zharen351991/article/details/81188097