InheritableThreadLocal变量的可见性

InheritableThreadLocal类继承于ThreadLocal类,所以它具有ThreadLocal类的特性,但又是一种特殊的ThreadLocal,其特殊性在于InheritableThreadLocal变量值会自动传递给所有子线程,而普通ThreadLocal变量不行。那么子线程是否可以修改InheritableThreadLocal变量值然后反向传递给主线程了?我们先来看一组测试代码和结果:

import java.util.concurrent.TimeUnit;public class TestThreadLocal {private static ThreadLocal<String> stringItl = new InheritableThreadLocal<String>(){protected String initialValue() {System.out.println(Thread.currentThread().getName() + ” initialize stringItl variable.”);return “String init”;}};private static ThreadLocal<String> stringItl2 = new InheritableThreadLocal<String>(){protected String initialValue() {System.out.println(Thread.currentThread().getName() + ” initialize stringItl2 variable.”);return “String2 init”;}};private static ThreadLocal<StringBuffer> stringBufferItl = new InheritableThreadLocal<StringBuffer>(){protected StringBuffer initialValue() {System.out.println(Thread.currentThread().getName() + ” initialize stringBufferItl variable.”);return new StringBuffer(“StringBuffer init”);}};private static ThreadLocal<StringBuffer> stringBufferItl2 = new InheritableThreadLocal<StringBuffer>(){protected StringBuffer initialValue() {System.out.println(Thread.currentThread().getName() + ” initialize stringBufferItl2 variable.”);return new StringBuffer(“StringBuffer2 init”);}};public static void main(String[] args) throws InterruptedException {stringItl.set(“Parent”);stringBufferItl.set(new StringBuffer(“ParentBuffer”));System.out.println(Thread.currentThread().getName() + ” first get stringItl : ” + stringItl.get());System.out.println(Thread.currentThread().getName() + ” first get stringBufferItl : ” + stringBufferItl.get().toString());for(int i=0; i<2; i++){new Thread(){public void run(){System.out.println(Thread.currentThread().getName() + ” first get stringItl : ” + stringItl.get());stringItl.set(Thread.currentThread().getName() + “Child”);System.out.println(Thread.currentThread().getName() + ” get after set stringItl : ” + stringItl.get());System.out.println(Thread.currentThread().getName() + ” first get stringItl2 : ” + stringItl2.get());stringItl2.set(Thread.currentThread().getName() + “Child”);System.out.println(Thread.currentThread().getName() + ” get after set stringItl2 : ” + stringItl2.get());System.out.println(Thread.currentThread().getName() + ” first get stringBufferItl : ” + stringBufferItl.get().toString());stringBufferItl.get().append(Thread.currentThread().getName());System.out.println(Thread.currentThread().getName() + ” get after set stringBufferItl : ” + stringBufferItl.get().toString());System.out.println(Thread.currentThread().getName() + ” first get stringBufferIt2 : ” + stringBufferItl2.get().toString());stringBufferItl2.get().append(Thread.currentThread().getName());System.out.println(Thread.currentThread().getName() + ” get after set stringBufferItl2 : ” + stringBufferItl2.get().toString());}}.start();}for(int i=0; i<2; i++){new Thread(){public void run(){System.out.println(Thread.currentThread().getName() + ” first get stringItl : ” + stringItl.get());stringItl.set(Thread.currentThread().getName() + “Child”);System.out.println(Thread.currentThread().getName() + ” get after set stringItl : ” + stringItl.get());System.out.println(Thread.currentThread().getName() + ” first get stringItl2 : ” + stringItl2.get());stringItl2.set(Thread.currentThread().getName() + “Child”);System.out.println(Thread.currentThread().getName() + ” get after set stringItl2 : ” + stringItl2.get());System.out.println(Thread.currentThread().getName() + ” first get stringBufferItl : ” + stringBufferItl.get().toString());stringBufferItl.set(new StringBuffer(Thread.currentThread().getName() + “Buffer”));System.out.println(Thread.currentThread().getName() + ” get after set stringBufferItl : ” + stringBufferItl.get().toString());System.out.println(Thread.currentThread().getName() + ” first get stringBufferIt2 : ” + stringBufferItl2.get().toString());stringBufferItl2.get().append(Thread.currentThread().getName());System.out.println(Thread.currentThread().getName() + ” get after set stringBufferItl2 : ” + stringBufferItl2.get().toString());}}.start();}TimeUnit.SECONDS.sleep(2);//let children threads run firstSystem.out.println(Thread.currentThread().getName() + ” second get stringItl : ” + stringItl.get());System.out.println(Thread.currentThread().getName() + ” first get stringItl2 : ” + stringItl2.get());System.out.println(Thread.currentThread().getName() + ” second get stringBufferItl : ” + stringBufferItl.get().toString());System.out.println(Thread.currentThread().getName() + ” first get stringBufferItl2 : ” + stringBufferItl2.get().toString());}}

代码运行结果:

main first get stringItl : Parentmain first get stringBufferItl : ParentBufferThread-0 first get stringItl : ParentThread-0 get after set stringItl : Thread-0ChildThread-0 initialize stringItl2 variable.Thread-0 first get stringItl2 : String2 initThread-0 get after set stringItl2 : Thread-0ChildThread-0 first get stringBufferItl : ParentBufferThread-0 get after set stringBufferItl : ParentBufferThread-0Thread-0 initialize stringBufferItl2 variable.Thread-0 first get stringBufferIt2 : StringBuffer2 initThread-0 get after set stringBufferItl2 : StringBuffer2 initThread-0Thread-1 first get stringItl : ParentThread-1 get after set stringItl : Thread-1ChildThread-1 initialize stringItl2 variable.Thread-1 first get stringItl2 : String2 initThread-1 get after set stringItl2 : Thread-1ChildThread-1 first get stringBufferItl : ParentBufferThread-0Thread-1 get after set stringBufferItl : ParentBufferThread-0Thread-1Thread-1 initialize stringBufferItl2 variable.Thread-1 first get stringBufferIt2 : StringBuffer2 initThread-1 get after set stringBufferItl2 : StringBuffer2 initThread-1Thread-3 first get stringItl : ParentThread-3 get after set stringItl : Thread-3ChildThread-3 initialize stringItl2 variable.Thread-3 first get stringItl2 : String2 initThread-3 get after set stringItl2 : Thread-3ChildThread-3 first get stringBufferItl : ParentBufferThread-0Thread-1Thread-3 get after set stringBufferItl : Thread-3BufferThread-3 initialize stringBufferItl2 variable.Thread-3 first get stringBufferIt2 : StringBuffer2 initThread-3 get after set stringBufferItl2 : StringBuffer2 initThread-3Thread-2 first get stringItl : ParentThread-2 get after set stringItl : Thread-2ChildThread-2 initialize stringItl2 variable.Thread-2 first get stringItl2 : String2 initThread-2 get after set stringItl2 : Thread-2ChildThread-2 first get stringBufferItl : ParentBufferThread-0Thread-1Thread-2 get after set stringBufferItl : Thread-2BufferThread-2 initialize stringBufferItl2 variable.Thread-2 first get stringBufferIt2 : StringBuffer2 initThread-2 get after set stringBufferItl2 : StringBuffer2 initThread-2main second get stringItl : Parentmain initialize stringItl2 variable.main first get stringItl2 : String2 initmain second get stringBufferItl : ParentBufferThread-0Thread-1main initialize stringBufferItl2 variable.main first get stringBufferItl2 : StringBuffer2 init

从运行结果可以看出:

可就是这样,还是有人,期望过多的温暖。

InheritableThreadLocal变量的可见性

相关文章:

你感兴趣的文章:

标签云: