Java同時プログラミング-TheadLocalの原理
3062 ワード
夜中にThreadLocalを研究したが、頭がはっきりしていないので、疑問があれば、検討を歓迎しましょう.
コア
ThreadクラスにはThreadLocalがある.ThreadLocalMap threadLocals = null; 変数#ヘンスウ#
ThreadLocalMapクラスの主要コード:
弱い参照の内部クラス
構築方法
ThreadLocalクラス
ThreadLocalへのデータのアクセス方法を見てみましょう.
最初にデータを格納するとき、現在のスレッドの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()などの自分の行為だけで、他の仕事を含まないべきではないからです.
書くのが少し乱れていて、よく考えを整理していません.
コア
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()などの自分の行為だけで、他の仕事を含まないべきではないからです.
書くのが少し乱れていて、よく考えを整理していません.