Java中的ThreadLocal类允许我们创建只能被同一个线程读写的变量。因此,如果一段代码含有一个ThreadLocal变量的引用,即使两个线程同时执行这段代码,它们也无法访问到对方的ThreadLocal变量。

如何创建ThreadLocal变量

以下代码展示了如何创建一个ThreadLocal变量:

1 private ThreadLocal myThreadLocal = new ThreadLocal();

我们可以看到,通过这段代码实例化了一个ThreadLocal对象。我们只需要实例化对象一次,并且也不需要知道它是被哪个线程实例化。虽然所有的线程都能访问到这个ThreadLocal实例,但是每个线程却只能访问到自己通过调用ThreadLocal的set()方法设置的值。即使是两个不同的线程在同一个ThreadLocal对象上设置了不同的值,他们仍然无法访问到对方的值。

如何访问ThreadLocal变量

一旦创建了一个ThreadLocal变量,你可以通过如下代码设置某个需要保存的值:

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

可以通过下面方法读取保存在ThreadLocal变量中的值:

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

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

为ThreadLocal指定泛型类型

我们可以创建一个指定泛型类型的ThreadLocal对象,这样我们就不需要每次对使用get()方法返回的值作强制类型转换了。下面展示了指定泛型类型的ThreadLocal例子:

1 private ThreadLocal myThreadLocal = new ThreadLocal<String>();

现在我们只能往ThreadLocal对象中存入String类型的值了。

并且我们从ThreadLocal中获取值的时候也不需要强制类型转换了。

如何初始化ThreadLocal变量的值

由于在ThreadLocal对象中设置的值只能被设置这个值的线程访问到,线程无法在ThreadLocal对象上使用set()方法保存一个初始值,并且这个初始值能被所有线程访问到。

但是我们可以通过创建一个ThreadLocal的子类并且重写initialValue()方法,来为一个ThreadLocal对象指定一个初始值。就像下面代码展示的那样:

1 private ThreadLocal myThreadLocal = new ThreadLocal<String>() {
2  
3     @Override
4     protected String initialValue() {
5         return "This is the initial value";
6     }
7  
8 };

一个完整的ThreadLocal例子

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

01 public class ThreadLocalExample {
02  
03     public static class MyRunnable implements Runnable {
04  
05         private ThreadLocal threadLocal = new ThreadLocal();
06  
07         @Override
08         public void run() {
09             threadLocal.set((int) (Math.random() * 100D));
10             try {
11             Thread.sleep(2000);
12             catch (InterruptedException e) {
13  
14             }
15             System.out.println(threadLocal.get());
16         }
17     }
18  
19     public static void main(String[] args) {
20          MyRunnable sharedRunnableInstance = new MyRunnable();
21          Thread thread1 = new Thread(sharedRunnableInstance);
22          Thread thread2 = new Thread(sharedRunnableInstance);
23          thread1.start();
24          thread2.start();
25     }
26  
27 }

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

关于InheritableThreadLocal

InheritableThreadLocal类是ThreadLocal类的子类。ThreadLocal中每个线程拥有它自己的值,与ThreadLocal不同的是,InheritableThreadLocal允许一个线程以及该线程创建的所有子线程都可以访问它保存的值。

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

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: Java ThreadLocal的使用

原文链接  作者: Jakob Jenkov 译者: 林威建[weakielin@gmail.com]

Java ThreadLocal的使用的更多相关文章

  1. Java ThreadLocal 源代码分析

    Java ThreadLocal 之前在写SSM项目的时候使用过一个叫PageHelper的插件 可以自动完成分页而不用手动写SQL limit 用起来大概是这样的 最开始的时候觉得很困惑,因为直接使 ...

  2. java threadLocal的初探

    在网上找了半天,终于找到一篇靠谱的文章了. 文章地址:http://qifuguang.me/2015/09/02/[Java%E5%B9%B6%E5%8F%91%E5%8C%85%E5%AD%A6% ...

  3. Java ThreadLocal Example(java中的ThreadLocal例子)

    Java ThreadLocal is used to create thread local variables. We know that all threads of an Object sha ...

  4. Java ThreadLocal

    ThreadLocal类,代表一个线程局部变量,通过把数据放在ThreadLocal中,可以让每个线程创建一个该变量的副本.也可以看成是线程同步的另一种方式吧,通过为每个线程创建一个变量的线程本地副本 ...

  5. 【01-14】java ThreadLocal工具类

    自定义ThreadLocal package concurrent; import java.util.HashMap; import java.util.Map; /** * @author alo ...

  6. Java ThreadLocal 理解

    ThreadLocal 概念: ThreadLocal不是用来解决对象共享访问的问题,而主要是提供了保存对象的方法和避免参数传递的方便的对象访问方式. ThreadLocal并不是一个Thread,而 ...

  7. Java ThreadLocal的使用案例

    本文以数据库操作Dao为例进行描述ThreadLocal的使用,如下是一个反例: package com.daxin.threadlocal.dao; import java.sql.Connecti ...

  8. 理解Java ThreadLocal

    ThreadLocal是什么 早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地 ...

  9. Java ThreadLocal (Java代码实战-006)

    ThreadLocal解决什么问题 由于 ThreadLocal 支持范型,如 ThreadLocal< StringBuilder >,为表述方便,后文用 变量 代表 ThreadLoc ...

随机推荐

  1. Java内存泄漏问题

    1:java中垃圾回收机制主要完成下面两件事情: 跟踪并监控每个java对象,当某个对象处于不可达状态时,回收该对象所占的内存 清理内存分配,回收过程中产生的内存碎片 2:对于JVM的垃圾回收机制来说 ...

  2. LeetCode(52):N皇后 II

    Hard! 题目描述: n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给定一个整数 n,返回 n 皇后不同的解决方 ...

  3. cf777c 模拟

    水题 /* 按列扫描一次矩阵,每个行向上最长sort长度即可 */ #include<bits/stdc++.h> using namespace std; #define ll long ...

  4. Java容器---字符容器StringBuffer & StringBuilder

    1.字符串对象 (1)定义 ---String 字符串常量,是不可改变的量,也就是创建后就不能在修改了: --- StringBuffer 字符串变量(线程安全),StringBuffer对象的值都是 ...

  5. python 全栈开发,Day115(urlencode,批量操作,快速搜索,保留原搜索条件,自定义分页,拆分代码)

    今日内容前戏 静态字段和字段 先来看下面一段代码 class Foo: x = 1 # 类变量.静态字段.静态属性 def __init__(self): y = 6 # 实例变量.字段.对象属性 # ...

  6. 2018-2019 2 20165203 《网络对抗技术》 Exp4 恶意代码分析

    2018-2019 2 20165203 <网络对抗技术> Exp4 恶意代码分析 实验要求 监控你自己系统的运行状态,看有没有可疑的程序在运行. 分析一个恶意软件,就分析Exp2或Exp ...

  7. bootstrap 强调相关的类

    .text-muted:提示,使用浅灰色(#999) .text-primary:主要,使用蓝色(#428bca) .text-success:成功,使用浅绿色(#3c763d) .text-info ...

  8. DDD领域模型数据访问权限(九)

    权限分为:数据权限和功能权限 数据权限: 查询提供附加表达式的支持: //提供附加表达式的支持 List<TAggreateRoot> GetByCondition(Expression& ...

  9. HDU 1851 (N个BASH博弈子游戏)

    题意:n堆石子,分别有M1,M2,·······,Mn个石子,各堆分别最多取L1,L2,·····Ln个石头,两个人分别取,一次只能从一堆中取,取走最后一个石子的人获胜.后选的人获胜输出Yes,否则输 ...

  10. A. 【UR #17】滑稽树上滑稽果

    题解: 首先很显然的是这是一条链(特殊数据说是链是故意让人迷茫的??) 然后 自己就开始yy 觉得每一次是加入一个使得当前值最小的数 然而这tm又是特殊数据?? 那就写一波发现是错的 考虑一下特殊数据 ...