【Java ThreadLocal的使用】

原文连接  做者: Jakob Jenkov 译者: 林威建[weakielin@gmail.com]html

Java中的ThreadLocal类容许咱们建立只能被同一个线程读写的变量。所以,若是一段代码含有一个ThreadLocal变量的引用,即便两个线程同时执行这段代码,它们也没法访问到对方的ThreadLocal变量。java

如何建立ThreadLocal变量

如下代码展现了如何建立一个ThreadLocal变量:dom

[size=1em][size=1em]

1ide

private ThreadLocal myThreadLocal = new ThreadLocal();post




咱们能够看到,经过这段代码实例化了一个ThreadLocal对象。咱们只须要实例化对象一次,而且也不须要知道它是被哪一个线程实例化。虽然全部的线程都能访问到这个ThreadLocal实例,可是每一个线程却只能访问到本身经过调用ThreadLocal的set()方法设置的值。即便是两个不一样的线程在同一个ThreadLocal对象上设置了不一样的值,他们仍然没法访问到对方的值。spa

如何访问ThreadLocal变量

一旦建立了一个ThreadLocal变量,你能够经过以下代码设置某个须要保存的值:线程

[size=1em][size=1em]

1htm

myThreadLocal.set("A thread local value”);对象




能够经过下面方法读取保存在ThreadLocal变量中的值:继承

[size=1em][size=1em]

1

String threadLocalValue = (String) myThreadLocal.get();




get()方法返回一个Object对象,set()对象须要传入一个Object类型的参数。

为ThreadLocal指定泛型类型

咱们能够建立一个指定泛型类型的ThreadLocal对象,这样咱们就不须要每次对使用get()方法返回的值做强制类型转换了。下面展现了指定泛型类型的ThreadLocal例子:

[size=1em][size=1em]

1

private ThreadLocal myThreadLocal = newThreadLocal<String>();




如今咱们只能往ThreadLocal对象中存入String类型的值了。

而且咱们从ThreadLocal中获取值的时候也不须要强制类型转换了。

如何初始化ThreadLocal变量的值

因为在ThreadLocal对象中设置的值只能被设置这个值的线程访问到,线程没法在ThreadLocal对象上使用set()方法保存一个初始值,而且这个初始值能被全部线程访问到。

可是咱们能够经过建立一个ThreadLocal的子类而且重写initialValue()方法,来为一个ThreadLocal对象指定一个初始值。就像下面代码展现的那样:

  1. private ThreadLocal myThreadLocal = new ThreadLocal<String>() {


  2.     @Override


  3.     protected String initialValue() {


  4.         return "This is the initial value";


  5.     }

  6. };


复制代码

一个完整的ThreadLocal例子

下面是一个完整的可执行的ThreadLocal例子:


  1. public class ThreadLocalExample {

  2. public static class MyRunnable implements Runnable {


  3.         private ThreadLocal threadLocal = new ThreadLocal();


  4. @Override

  5. public void run() {


  6.             threadLocal.set((int) (Math.random() * 100D));

  7. try {


  8.             Thread.sleep(2000);


  9.             } catch (InterruptedException e) {


  10. }


  11.             System.out.println(threadLocal.get());


  12.         }


  13.     }


  14.     public static void main(String[] args) {


  15.          MyRunnable sharedRunnableInstance = new MyRunnable();


  16.          Thread thread1 = new Thread(sharedRunnableInstance);


  17.          Thread thread2 = new Thread(sharedRunnableInstance);


  18.          thread1.start();


  19.          thread2.start();


  20.     }

  21. }


复制代码

面的例子建立了一个MyRunnable实例,并将该实例做为参数传递给两个线程。两个线程分别执行run()方法,而且都在ThreadLocal实例上保存了不一样的值。若是它们访问的不是ThreadLocal对象而且调用的set()方法被同步了,则第二个线程会覆盖掉第一个线程设置的值。可是,因为它们访问的是一个ThreadLocal对象,所以这两个线程都没法看到对方保存的值。也就是说,它们存取的是两个不一样的值。

关于InheritableThreadLocal

InheritableThreadLocal类是ThreadLocal类的子类。ThreadLocal中每一个线程拥有它本身的值,与ThreadLocal不一样的是,InheritableThreadLocal容许一个线程以及该线程建立的全部子线程均可以访问它保存的值。

【注:全部子线程都会继承父线程保存的ThreadLocal值】

原创文章,转载请注明: 转载自ifeve.com

相关文章
相关标签/搜索