ThreadLocalの<T>分析コード

私たちは、内部実装activeJDBCのフレームワークを参照ThreadLocalの各ユニークな接続スレッドのために、このクラスレコードを

private static final ThreadLocal<HashMap<String, Connection>> connectionsTL = new ThreadLocal<>();

気持ちは知識、オープンソースの外観です。説明では、ソースコードを見てください

このクラスはスレッドローカル変数を提供します。これらの変数は、(その取得または設定メソッドを介して)1にアクセスする各スレッドは変数の独自の、独立して、初期化コピーを持っていることで正常な対応とは異なります。ThreadLocalのインスタンスは、通常のスレッド(例えば、ユーザIDやトランザクションID)との自由連合を希望するクラスでプライベート静的フィールドです。

この論文の鳥、ブラインドは何を翻訳し、これは次のとおりです。

このクラスは、排他的なスレッドの変数を提供します。これらの変数は、他の通常の変数と異なっている、それはそれぞれのスレッドが独自の独立変数を持つ(getおよびsetメソッドを通じて)初期化されていることです。このタイプの例としては、一般的に、各スレッドを実装するプライベート静的クラスの分野で使用されている自身の状態(例えばuserIdを、トランザクションIDなど)。

それの使用についてXianpao、

package com.test.threadlocal;

public class TestController {
    
    private static int index = 0;
    private static String str = "这个字符串是每个线程共享的";
    // 这个变量,看似是一个类的静态属性,实则是每个线程有自己独有的区域
    private static ThreadLocal<String> threadStr = new ThreadLocal<String>() {
        @Override
        protected String initialValue() {
            return "main线程专享";
        }
    };      
    
    public static void main(String[] args) throws InterruptedException {
        for(int i = 0; i < 3; i++) {
            Thread t = new MyThread();
            t.start();
            t.join();
        }
        
        System.out.println(str);
        System.out.println(threadStr.get());
    }
    
    static class MyThread extends Thread{

        @Override
        public void run() {
            index++;
            str = "第" + index + "个str";
            threadStr.set("第" + index + "个threadStr");
        }
        
        
    }

}

この例では、結果は印刷とthreadStr STR変数から見ることができます。strのすべてのスレッドが読み取りおよび書き込みは、各スレッド内threadStrはスレッド専有面積を開きました。次に、我々は、実装を見てください。
コンストラクタを見てください

     /**
     * ThreadLocals rely on per-thread linear-probe hash maps attached
     * to each thread (Thread.threadLocals and
     * inheritableThreadLocals).  The ThreadLocal objects act as keys,
     * searched via threadLocalHashCode.  This is a custom hash code
     * (useful only within ThreadLocalMaps) that eliminates collisions
     * in the common case where consecutively constructed ThreadLocals
     * are used by the same threads, while remaining well-behaved in
     * less common cases.
     */
    private final int threadLocalHashCode = nextHashCode();
     /**
     * Creates a thread local variable.
     * @see #withInitial(java.util.function.Supplier)
     */
    public ThreadLocal() {
    }

コンストラクタは、しかし、クラスはプライベート整数定数を持っている、空であるthreadLocalHashCodeをnextHashCode()私たちは、深い海のような地方の源として、読んでいない方法。見ている温家宝の鳥は、その後、おそらくそれぞれの新しいThreadLocalの変数、それは後の非極端な状況である整数を法のハッシュコードを生成します簡単な紛争のではありません(この文は、ビットは、実際には、それを失ったI知っている)していない
と、その後のセット方法を見て

/**
     * Sets the current thread's copy of this thread-local variable
     * to the specified value.  Most subclasses will have no need to
     * override this method, relying solely on the {@link #initialValue}
     * method to set the values of thread-locals.
     *
     * @param value the value to be stored in the current thread's copy of
     *        this thread-local.
     */
    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

簡単には、現在のスレッドに相当し、独自の値それぞれのスレッドを設定するこの方法は、キーであることを確認し、その後に来るThreadLocalMap各スレッドが複数の値を保持することができますマッピングされ、私たちは私が特定の値を保存することを推測するマップの値は、それはObjectクラスの宣言であると推定されているので明らかに、このマップは、当然のことながら、雌ねじを保存するために使用されます。それはどのようなキーですか?我々はコンストラクタThreadLocalMapクラスを見て。

/**
         * The table, resized as necessary.
         * table.length MUST always be a power of two.
         */
        private Entry[] table;
                
/**
         * Construct a new map initially containing (firstKey, firstValue).
         * ThreadLocalMaps are constructed lazily, so we only create
         * one when we have at least one entry to put in it.
         */
        ThreadLocalMap(ThreadLocal<?> 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);
        }

何と言うこと!このクラスは、私たちの想像のHashMapの継承していない、またはConcurrentMapが、単に持って、無意味にない淡あるのHashMapの実装と地図の実現を見つけることができる必要があり、学生の実現の内部の地図をお読みください。これは、コンストラクタで、次の手順を行いました。

  1. 16エントリの配列のサイズを初期化します
  2. 上記を通じて非常にファンのハッシュコードのハッシュ値取得モジュロ15指標値が配列に格納されていると言わ
  3. その後、建設エントリ、およびに保存
  4. 長さは1に設定されています
  5. サイズ16 2/3の拡大を制限するために設定します

私たちは、ササの水の友人を感じ、私たちはHashMapの実装を見てきました、これは地図まあを達成するために、配列を使用することです表示されません。
セットの地図や取得方法が分析されていません。すべての後、我々はまだ、出固執しなければならないのThreadLocalの方法を取得し、どのような私たちの主な分析であります

/**
     * Returns the value in the current thread's copy of this
     * thread-local variable.  If the variable has no value for the
     * current thread, it is first initialized to the value returned
     * by an invocation of the {@link #initialValue} method.
     *
     * @return the current thread's value of this thread-local
     */
    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }

目に見える、現在のスレッドが地図を取得するためのキーとして使用され得るために、この電流でのエントリーエンティティを取得。最後に、当然のことながら、値の店に行きます。

私は〜私は幸せです、コーディングしています

ブログ記事複数のプラットフォームからこの記事OpenWriteリリース!

おすすめ

転載: www.cnblogs.com/theone67/p/11884581.html