Java-ThreadLocalクラス
5224 ワード
一、ThreadLocalを導入する
テスト、ThreadLocalがない場合:
テスト結果:
結果は混乱し,2つのスレッドの実行は明らかに交差していることが分かった.
ThreadLocalを使用した後:
結果:
スレッドローカル変数を使用した後、getメソッドとsetメソッドで変数を読み書きする必要があります.
二、簡単にThreadLocalを紹介する
変数の初期化操作はここで完了し、デフォルトはnullを返し、overrideという方法を提案し、getの前にset操作が行われていることを確認し、getの時にエラーが発生しないようにします.
ThreadLocalクラスには、keyを現在のthreadLocalとするobjectが格納された内部静的クラスThreadLocalMapがある.
/* ThreadLocal
* ThreadLocal: 。
* ( get set ) 。
* 。 ,
* 。 , , 。
* , 。
ThreadLocal , 。
JDK1.5 ThreadLocal , ThreadLocal, T 。
ThreadLocal get set T 。 ThreadLocal ,
T 。 Threadlocal
public , get() set () 。
inintValue() protected 。 。
: initValue(), null 。 set , get ,
get initValue 。 , get null 。
set 。 get set ,
initValue , 。
* */
テスト、ThreadLocalがない場合:
public class TestThreadLocal {
public static int a = 0;
public static void main(String[] args) {
MyThread myThread=new MyThread();
myThread.start();
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+":"+a);
}
}
public static class MyThread extends Thread {
public void run(){
for(int i=0;i<5;i++){
a=++a;
System.out.println(Thread.currentThread().getName()+":"+a);
}
}
}
}
テスト結果:
main:1
main:2
main:3
main:4
main:5
Thread-0:6
Thread-0:7
Thread-0:8
Thread-0:9
Thread-0:10
結果は混乱し,2つのスレッドの実行は明らかに交差していることが分かった.
ThreadLocalを使用した後:
public class TestThreadLocal {
//public static int a = 0;
public static ThreadLocal a=new ThreadLocal(){
public Integer initialValue(){// a
return 0;
}
};
public static void main(String[] args) {
MyThread myThread=new MyThread();
myThread.start();
for(int i=0;i<5;i++){
//a=++a;
a.set(a.get()+1);
System.out.println(Thread.currentThread().getName()+":"+a.get());
}
}
public static class MyThread extends Thread {
public void run(){
for(int i=0;i<5;i++){
//a=++a;
a.set(a.get()+1);
System.out.println(Thread.currentThread().getName()+":"+a.get());
}
}
}
}
結果:
Thread-0:1
Thread-0:2
Thread-0:3
Thread-0:4
Thread-0:5
main:1
main:2
main:3
main:4
main:5
スレッドローカル変数を使用した後、getメソッドとsetメソッドで変数を読み書きする必要があります.
二、簡単にThreadLocalを紹介する
/**
* Returns the current thread's "initial value" for this
* thread-local variable. This method will be invoked the first
* time a thread accesses the variable with the {@link #get}
* method, unless the thread previously invoked the {@link #set}
* method, in which case the initialValue method will not
* be invoked for the thread. Normally, this method is invoked at
* most once per thread, but it may be invoked again in case of
* subsequent invocations of {@link #remove} followed by {@link #get}.
*
* This implementation simply returns null; if the
* programmer desires thread-local variables to have an initial
* value other than null, ThreadLocal must be
* subclassed, and this method overridden. Typically, an
* anonymous inner class will be used.
*
* @return the initial value for this thread-local
*/
protected T initialValue() {
return null;
}
変数の初期化操作はここで完了し、デフォルトはnullを返し、overrideという方法を提案し、getの前にset操作が行われていることを確認し、getの時にエラーが発生しないようにします.
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();
}
ThreadLocalクラスには、keyを現在のthreadLocalとするobjectが格納された内部静的クラスThreadLocalMapがある.
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
setメソッドも で、ThreadLocalに っている は この2つのメソッドで されます.ああ、removeもあります.
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
コード... まず て、それから たちのspringソースの に り えて、これはただのエピソードです.