Java ThreadLocal类

最近项目重构的时候,接触到了ThreadLocal这个类,才知道原来关于线程还有这么个东东,真是疏漏寡闻了。

ThreadLocal类是做什么用的呢?

网上Copy了一段英文的介绍:The ThreadLocal class in Java enables you to create variables that can only be read and written by the same thread. Thus, even if two threads are executing the same code, and the code has a reference to a ThreadLocal variable, then the two threads cannot see each other’s ThreadLocal variables.

通俗点讲就是通过ThreadLocal类,可以为线程创建一些对象(变量)放在ThreadLocal对象中,之后只有同地线程可以从ThreadLocal对象中取回这些对象(变量),其它线程访问相同的ThreadLocal类只有获取自己保存的对象(变量)。

来看一个例子。

import java.util.concurrent.TimeUnit;public class App {public static final ThreadLocal<String> threadId = new ThreadLocal<String>();public static void main(String[] args) {for (int i = 1; i<= 10; i++) {new TheThread("id" + i).start();}}}class TheThread extends Thread {private String id;TheThread(String id) {this.id = id;}@Overridepublic void run() {App.threadId.set(id);try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}System.out.println( id.endsWith(App.threadId.get()) );}}

App类初始化了唯一一个static final的ThreadLocal对象threadId,之后启动10个TheThread线程。每个线程在创建时把参数id保存到自己的私有成员id中,在执行的时候,把自己的id保存到唯一的hreadId对象t中,然后sleep5秒,目的是让所有的线程都访问过threadId后,再输出最后的System.out。结果大家应该猜到了吧,就是输出10行true。ThreadLocal的get()方法返回的结果要么是空,要么是当前线程自己先前存放的东西,别的线程无法获取,很容易理解,但是很有用的一个类。

如果一个线程在没有存值前就调用ThreadLocal.get()方法,返回值会是null。如果希望ThreadLocal在这种情况下返回一个默值,可以在初始化ThreadLocal时创建一个匿名内部类,覆盖initialValue()方法:

public static final ThreadLocal<String> threadId = new ThreadLocal<String>(){@Overrideprotected String initialValue() {return "the default thing";}};

ThreadLocal还有一个子类InheritableThreadLocal,顾名思义就是子线程可以访问父线程存放到ThreadLocal中的对象(变量),来看个例子:

public class App {public static final ThreadLocal<String> threadLocal = new InheritableThreadLocal<String>();public static void main(String[] args) {threadLocal.set("idRoot");new Thread(){public void run() {threadLocal.set("first parent thread");new TheThread().start();new TheThread().start();}}.start();new Thread(){public void run() {threadLocal.set("second parent thread");new TheThread().start();new TheThread().start();}}.start();}}class TheThread extends Thread {@Overridepublic void run() {System.out.println( App.threadLocal.get() );}}

代码很简单,就不解释了,输出结果是两行first parent thread和两行second parent thread,但顺序会不一样。

而消极的人则在每个机会都看到某种忧患。

Java ThreadLocal类

相关文章:

你感兴趣的文章:

标签云: