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

如何创建ThreadLocal变量

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

private ThreadLocal myThreadLocal = new ThreadLocal();

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

如何访问ThreadLocal变量

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

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

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

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

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

为ThreadLocal指定泛型类型

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

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

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

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

如何初始化ThreadLocal变量的值

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

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

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

    @Override
protected String initialValue() {
return "This is the initial value";
} };

一个完整的ThreadLocal例子

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

public class ThreadLocalExample {

    public static class MyRunnable implements Runnable {

        private ThreadLocal threadLocal = new ThreadLocal();

        @Override
public void run() {
threadLocal.set((int) (Math.random() * 100D));
try {
Thread.sleep(2000);
} catch (InterruptedException e) { }
System.out.println(threadLocal.get());
}
} public static void main(String[] args) {
MyRunnable sharedRunnableInstance = new MyRunnable();
Thread thread1 = new Thread(sharedRunnableInstance);
Thread thread2 = new Thread(sharedRunnableInstance);
thread1.start();
thread2.start();
} }

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

关于InheritableThreadLocal

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

最后

私信回复 资料 领取一线大厂Java面试题总结+阿里巴巴泰山手册+各知识点学习思维导+一份300页pdf文档的Java核心知识点总结!

这些资料的内容都是面试时面试官必问的知识点,篇章包括了很多知识点,其中包括了有基础知识、Java集合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日记、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构等等。

还不会使用Java ThreadLocal落后了吧!的更多相关文章

  1. Java ThreadLocal 源代码分析

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

  2. Java ThreadLocal的使用

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

  3. java threadLocal的初探

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

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

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

  5. 理解Java ThreadLocal

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

  6. java—ThreadLocal模式与OSIV模式(53)

    ThreadLocal: 维护线程局部的变量. ThreadLocal 不是线程.它就是一个Map.可以保存对象. 它保存的对象,只与当前线程相关. 当一个线程还没有运行完成时,如果不想传递数据,可以 ...

  7. java ThreadLocal(应用场景及使用方式及原理)

    尽管ThreadLocal与并发问题相关,可是很多程序猿只将它作为一种用于"方便传參"的工具,胖哥觉得这或许并非ThreadLocal设计的目的,它本身是为线程安全和某些特定场景的 ...

  8. java ThreadLocal线程设置私有变量底层源码分析

    前面也听说了ThreadLocal来实现高并发,以前都是用锁来实现,看了挺多资料的,发现其实还是区别挺大的(感觉严格来说ThreadLocal并不算高并发的解决方案),现在总结一下吧. 高并发中会出现 ...

  9. Java ThreadLocal

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

随机推荐

  1. Git文件合并

    两个分支:主分支master,分支pre 1.将pre分支文件合并到master分支: 切换到master分支下操作: 合并文件夹[如果是文件则为a.text b.text]: git checkou ...

  2. 《数据可视化之美》高清PDF全彩版|百度网盘免费下载|Python数据可视化

    <数据可视化之美>高清PDF全彩版|百度网盘免费下载|Python数据可视化 提取码:i0il 内容简介 <数据可视化之美>内容简介:可视化是数据描述的图形表示,旨在一目了然地 ...

  3. 枚举-称硬币POJ1013

    #include <iostream> #include<string.h> using namespace std; char Lleft[][]; char Lright[ ...

  4. Seaborn基础2

    import matplotlib.pyplot as plt import seaborn as sns import numpy as np def sinplot(flip = 1): x = ...

  5. Python Tuple(元组) tuple()方法

    描述 Python 元组 tuple() 函数将列表转换为元组.每组词 www.cgewang.com 语法 tuple()方法语法: tuple( iterable ) 参数 iterable -- ...

  6. PHP array_replace() 函数

    实例 使用第二个数组($a2)的值替换第一个数组($a1)的值: <?php$a1=array("red","green");$a2=array(&quo ...

  7. PHP readlink() 函数

    定义和用法 readlink() 函数返回符号连接的目标. 如果成功,该函数返回连接的目标.如果失败,则返回 FALSE. 语法 readlink(linkpath) 参数 描述 linkpath 必 ...

  8. luogu P4798 [CEOI2015 Day1]卡尔文球锦标赛 dp 数位dp

    LINK:卡尔文球锦标赛 可以先思考一下合法的序列长什么样子. 可以发现后面的选手可以使用前面出现的编号也可以直接自己新建一个队. 其实有在任意时刻i 序列的mex>max.即要其前缀子序列中1 ...

  9. luogu P2605 [ZJOI2010]基站选址 线段树优化dp

    LINK:基站选址 md气死我了l达成1结果一直调 显然一个点只建立一个基站 然后可以从左到右进行dp. \(f_{i,j}\)表示强制在i处建立第j个基站的最小值. 暴力枚举转移 复杂度\(n\cd ...

  10. 6.10 省选模拟赛 小C的利是 高斯消元 矩阵行列式

    LINK:小C的利是 想起来把这道题的题解写了 .一个常识:利是在广东那边叫做红包. 关于行列式的题目 不过我不太会23333..口胡还是可以的. 容易想到10分的状压.不过没什么意思. 仔细观察要求 ...