Java同時プログラミング-TheadLocalの原理

3062 ワード

夜中にThreadLocalを研究したが、頭がはっきりしていないので、疑問があれば、検討を歓迎しましょう.
コア
ThreadクラスにはThreadLocalがある.ThreadLocalMap threadLocals = null; 変数#ヘンスウ#
ThreadLocalMapクラスの主要コード:
弱い参照の内部クラス
static class Entry extends WeakReference<ThreadLocal> {
            /** The value associated with this ThreadLocal. */
      Object value;

      Entry(ThreadLocal k, Object v) {
          super(k);
          value = v;
      }
 }

構築方法
 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);
}
private Entry getEntry(ThreadLocal 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);
 }

ThreadLocalクラス
ThreadLocalへのデータのアクセス方法を見てみましょう.
 public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
    }

 public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
}

void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
}

最初にデータを格納するとき、現在のスレッドのthreadLocalsはnullであるため、現在のスレッドのThreadLocalオブジェクト(このオブジェクトは一般的に静的定数として設計されている)と、実際に格納する値に基づいてThreadLocalMapを作成し、ThreadクラスのthreadLocals変数、つまりThreadクラスのthreadLocals変数を初期化します.
データを取得する場合も、現在のスレッドに基づいて自分のThreadLocalMapを取得し、ThreadLocalオブジェクト【作成時に使用するオブジェクトと同一】で対応する値を取得します.
いくつかの説明:
1、使用中、最も核心的なのはThreadLocalMapであるべきである.スレッドの増減により変化するのもThreadLocalMapである.
2、ThreadLocalMapにおけるデータの格納は、プログラムで宣言されたThreadlocalオブジェクトをkeyとし、実際に必要な値はvalueとして格納される.一般にKeyは定数であるが,これもプログラム中のThreadLocalオブジェクトが一般的に静的定数として宣言される理由である.
3、Threadlocalが静的定数として設計されていない場合、どのような結果になるのでしょうか.
スレッドごとに作成されるのはThreadLocalMapオブジェクトです.プログラムごとに定義されるThreadLocalオブジェクトは、ThreadLocalMapオブジェクトのkeyに対応しています.Threadlocalが定数でない場合、サーバが実行中にThreadLocalオブジェクトの数は、アプリケーションに存在するスレッド数(スレッドが1つのThreadlocalに対応する場合)です.
ディスカッション:
使用中にコアとして機能するのがThreadLocalMapである以上、なぜThreadクラスで直接このMapを実現しないのでしょうか.
個人的な観点はソフトウェア設計の観点から考えられている.なぜなら、Threadに書くと、Threadの中の機能が多すぎて、機能の結合性が強すぎて、簡単に言えばThread自体がstart()、stop()、run()などの自分の行為だけで、他の仕事を含まないべきではないからです.
書くのが少し乱れていて、よく考えを整理していません.