日常記録-マルチスレッドと高同時性-ThreadLocalの概念、原理、使用、ThreadLocalとsynchronizedの比較


一、概念
ThreadLocal:スレッドローカル変数は、その変数を使用するスレッドごとに空間的に時間的に独立した変数のコピーを提供するため、各スレッドは、他のスレッドに対応するコピーに影響を与えることなく、独立して自分のコピーを変更することができます.現在のスレッドのmapオブジェクトとして理解でき、keyは現在のThreadLocal、valueは格納されたオブジェクトである.
二、原理
1.set():ThreadLocalは現在のスレッドに対してオブジェクトメソッドを格納し、現在のスレッドに対応するスレッドローカル変数ThreadLocal.ThreadLocalMapthreadLocalsの値を設定します.存在しない場合は作成し、hreadLocalをkeyとし、オブジェクトがvalueであるThreadLocalMapタイプのオブジェクトを現在のスレッドのthreadLocals属性に割り当てます.
  public void set(T value) {
  		//    
        Thread t = Thread.currentThread();
        //  ThreadLocalMap getMap(t)          threadLocals   	
        //threadLocals                    ThreadLocal.ThreadLocalMap  
        //ThreadLocalMap               Entry     k    ThreadLocal    v        
        //                  ThreadLocalMap    
        ThreadLocalMap map = getMap(t);
        if (map != null)
        	//        ThreadLocal     key ,        value
        	//    .threadLocals = 
            map.set(this, value);
        else
        	//           .threadLocals =         ThreadLocalMap    
        	//t.threadLocals = new ThreadLocalMap(this, firstValue);
            createMap(t, value);
    }

2.get():ThreadLocalは、現在のスレッドに対応するスレッドのローカル変数を返す現在のスレッドの過去のオブジェクトメソッドです.存在しない場合はnullを返します.
public T get() {
		//      
        Thread t = Thread.currentThread();
        //       threadLocals
        ThreadLocalMap map = getMap(t);
        if (map != null) {
        	//    threadLocals   Entry   Entry
        	//Entry       
        	//Object value;
        	//Entry      
        	//Entry(ThreadLocal> k, Object v) {
            //    super(k);
            //    value = v;
            //}  
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                //e             
                T result = (T)e.value;
                return result;
            }
        }
        //            threadLocals      value   null     null
        return setInitialValue();
    }

三、使用
public class ThreadLocalTest {

    public static void main(String[] args) {
        ThreadLocal<Person> threadLocal = new ThreadLocal<>();
        new Thread(() -> {
            threadLocal.set(new Person("  "));
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(threadLocal.get().name);
        }).start();
        new Thread(() -> {
            threadLocal.set(new Person("  "));
            System.out.println(threadLocal.get().name);
        }).start();
    }
}

class Person{

    String name;

    public Person(String name) {
        this.name = name;
    }

}

注意:springの明示的な宣言トランザクションはThreadLocalを使用しています.1つの物事内の削除変更は1つのconnectionに基づいているため、データとのインタラクションごとに新しいconnectionになることはできません.そのため、1つの物事内にThreadLocalで今回の物事のconnectionが格納されています.
四、ThreadLocalとsynchronizedの比較
ThreadLocal:スレッドごとに1つのオブジェクトリソース.synchronized:複数のスレッドが1つのオブジェクトリソースを競合します.注意:ThreadLocalに格納されているオブジェクトは、使用しない場合はremove()で回収する必要があります.そうしないと、メモリ漏洩のリスクがあります.