001package net.gdface.utils;
002
003/**
004 * 基于Thread Local Storage的双重检查锁定实现{@link ILazyInitVariable}的抽象类<br>
005 * 原理说明参见<a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html">《The "Double-Checked Locking is Broken" Declaration》</a><br>
006 * @author guyadong
007 *
008 * @param <T> variable type
009 */
010public abstract class BaseTls<T> extends ILazyInitVariable.BaseLazyVar<T> {
011        /**
012         * If perThreadInstance.get() returns a non-null value, this thread has done
013         * synchronization needed to see initialization of helper
014         */
015        @SuppressWarnings("rawtypes")
016        private final ThreadLocal perThreadInstance = new ThreadLocal();
017        private T var = null;
018
019        public BaseTls() {
020        }
021
022        @Override
023        public T get() {
024                if (null == perThreadInstance.get()) {
025                        initFieldNames();
026                }
027                return var;
028        }
029
030        @SuppressWarnings({ "unchecked" })
031        private void initFieldNames() {
032                synchronized (this) {
033                        if (null == var) {
034                                var = doGet();
035                        }
036                }
037                // Any non-null value would do as the argument here
038                perThreadInstance.set(perThreadInstance);
039        }
040}