Thread詳細解12:Inheitable ThreadLocalの使用


ThreadLocalの使い方は前の記事を参考にしてもいいです.http://blog.csdn.net/cds86333774/article/details/51020819Inheitable ThreadLocalはThreadLocalのサブクラスです.このクラスは、親スレッドから継承された値を子スレッドに提供するThreadLocalを拡張しています.子スレッドを作成すると、子スレッドは継承可能なスレッドのローカル変数の初期値をすべて受信し、親スレッドが持つ値を取得します.通常、子スレッドの値は親スレッドの値と一致する.しかし、このクラスのchild Value方法を書き換えることにより、子スレッドの値は親スレッド値の任意の関数として使用することができる.作成したすべてのサブスレッドに変数(ユーザIDやトランザクションIDなど)で維持されているスレッド属性毎に自動的に転送しなければならない場合、通常のスレッドローカル変数ではなく、可能な限り引き継ぎ可能なスレッドローカル変数を採用するべきである.
1サブスレッド
スレッドAがスレッドBを作成すると、BはAのサブスレッドである.
2コード例
使い方はThreadLocalとほぼ同じですが、効果は違います.
ThreadLocal Test.java
package threadLocalTest;

import java.util.Random;

public class ThreadLocalTest {
    private static ThreadLocal familyFortunes = new ThreadLocal() {
        @Override
        protected Integer initialValue() {
            Random random = new Random();
            return random.nextInt(1000);
        }
    };

    public static int get() {
        return familyFortunes.get();
    }

    public static void set(int value) {
        familyFortunes.set(value);
    }

}
Inheitable ThreadLocal Test.java
package threadLocalTest;

import java.util.Random;

public class InheritableThreadLocalTest {
    private static InheritableThreadLocal familyFortunes = new InheritableThreadLocal() {
        @Override
        protected Integer initialValue() {
            Random random = new Random();
            return random.nextInt(1000);
        }
    };

    public static int get() {
        return familyFortunes.get();
    }

    public static void set(int value) {
        familyFortunes.set(value);
    }

}
Thread 2.java
package threadLocalTest;

public class Thread2 extends Thread {

    public Thread2(String name) {
        super(name);
    }

    @Override
    public void run() {
        super.run();
        System.out.printf("%s   ThreadLocal    :%d
"
, Thread.currentThread().getName(), ThreadLocalTest.get()); System.out.printf("%s InheritableThreadLocal :%d
"
, Thread.currentThread().getName(), InheritableThreadLocalTest.get()); } public static void main(String[] args) { System.out.printf("%s ThreadLocal :%d
"
, Thread.currentThread().getName(), ThreadLocalTest.get()); System.out.printf("%s InheritableThreadLocal :%d
"
, Thread.currentThread().getName(), InheritableThreadLocalTest.get()); Thread2 t1 = new Thread2("Child1"); t1.start(); } }
出力
main   ThreadLocal    :444
main   InheritableThreadLocal    :401
Child1   ThreadLocal    :513
Child1   InheritableThreadLocal    :401
分析
  • の異なるスレッドがThreadLocal getデータに行きます.得られたのは自分と紐付けられたデータです.
  • サブスレッドがInherityable ThreadLocal getデータに行くと、親スレッドと同じデータ、すなわち子スレッドが親スレッドを引き継いだInheitable ThreadLocalのデータが得られ、このデータは「家族データ」
  • となります.
    3 child Value
    child Valueの方法の説明を見ましたが、やはり使い方が分かりません.ソースを見に来ました.
        /**
         * Computes the child's initial value for this inheritable thread-local
         * variable as a function of the parent's value at the time the child
         * thread is created.  This method is called from within the parent
         * thread before the child is started.
         * 

    * This method merely returns its input argument, and should be overridden * if a different behavior is desired. * * @param parentValue the parent thread's value * @return the child thread's initial value */ protected T childValue(T parentValue) { return parentValue; }

    元々この方法は、サブスレッドが最初にgetした時の初期値で、書き換えないと、デフォルトは親スレッドの値に戻りますので、上の例のコードの出力があります.フォームはThreadLocalのinitial Valueと似ています.
    以下、child Valueを書き直して、子スレッドの初期値を親スレッドの値+1とします.
    package threadLocalTest;
    
    import java.util.Random;
    
    public class InheritableThreadLocalTest {
        private static InheritableThreadLocal familyFortunes = new InheritableThreadLocal() {
            @Override
            protected Integer initialValue() {
                Random random = new Random();
                return random.nextInt(1000);
            }
    
            @Override
            protected Integer childValue(Integer parentValue) {
                return parentValue+1;
            }
    
    
        };
    
        public static int get() {
            return familyFortunes.get();
        }
    
        public static void set(int value) {
            familyFortunes.set(value);
        }
    
    
    
    }
    出力
    main   ThreadLocal    :506
    main   InheritableThreadLocal    :570
    Child1   ThreadLocal    :953
    Child1   InheritableThreadLocal    :571