当前位置: 首页 > 面试题库 >

请介绍一下ThreadLocal?

司徒云
2023-03-14
本文向大家介绍请介绍一下ThreadLocal?相关面试题,主要包含被问及请介绍一下ThreadLocal?时的应答技巧和注意事项,需要的朋友参考一下

ThreadLocal简介

通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决呢? JDK中提供的ThreadLocal类正是为了解决这样的问题。 ThreadLocal类主要解决的就是让每个线程绑定自己的值,可以将ThreadLocal类形象的比喻成存放数据的盒子,盒子中可以存储每个线程的私有数据。

如果你创建了一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的本地副本,这也是ThreadLocal变量名的由来。他们可以使用 get()set() 方法来获取默认值或将其值更改为当前线程所存的副本的值,从而避免了线程安全问题。

再举个简单的例子:

比如有两个人去宝屋收集宝物,这两个共用一个袋子的话肯定会产生争执,但是给他们两个人每个人分配一个袋子的话就不会出现这样的问题。如果把这两个人比作线程的话,那么ThreadLocal就是用来这两个线程竞争的。

ThreadLocal示例

相信看了上面的解释,大家已经搞懂 ThreadLocal 类是个什么东西了。

import java.text.SimpleDateFormat;
import java.util.Random;

public class ThreadLocalExample implements Runnable{

     // SimpleDateFormat 不是线程安全的,所以每个线程都要有自己独立的副本
    private static final ThreadLocal<SimpleDateFormat> formatter = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMdd HHmm"));

    public static void main(String[] args) throws InterruptedException {
        ThreadLocalExample obj = new ThreadLocalExample();
        for(int i=0 ; i<10; i++){
            Thread t = new Thread(obj, ""+i);
            Thread.sleep(new Random().nextInt(1000));
            t.start();
        }
    }

    @Override
    public void run() {
        System.out.println("Thread Name= "+Thread.currentThread().getName()+" default Formatter = "+formatter.get().toPattern());
        try {
            Thread.sleep(new Random().nextInt(1000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //formatter pattern is changed here by thread, but it won't reflect to other threads
        formatter.set(new SimpleDateFormat());

        System.out.println("Thread Name= "+Thread.currentThread().getName()+" formatter = "+formatter.get().toPattern());
    }

}

Output:

Thread Name= 0 default Formatter = yyyyMMdd HHmm
Thread Name= 0 formatter = yy-M-d ah:mm
Thread Name= 1 default Formatter = yyyyMMdd HHmm
Thread Name= 2 default Formatter = yyyyMMdd HHmm
Thread Name= 1 formatter = yy-M-d ah:mm
Thread Name= 3 default Formatter = yyyyMMdd HHmm
Thread Name= 2 formatter = yy-M-d ah:mm
Thread Name= 4 default Formatter = yyyyMMdd HHmm
Thread Name= 3 formatter = yy-M-d ah:mm
Thread Name= 4 formatter = yy-M-d ah:mm
Thread Name= 5 default Formatter = yyyyMMdd HHmm
Thread Name= 5 formatter = yy-M-d ah:mm
Thread Name= 6 default Formatter = yyyyMMdd HHmm
Thread Name= 6 formatter = yy-M-d ah:mm
Thread Name= 7 default Formatter = yyyyMMdd HHmm
Thread Name= 7 formatter = yy-M-d ah:mm
Thread Name= 8 default Formatter = yyyyMMdd HHmm
Thread Name= 9 default Formatter = yyyyMMdd HHmm
Thread Name= 8 formatter = yy-M-d ah:mm
Thread Name= 9 formatter = yy-M-d ah:mm

从输出中可以看出,Thread-0已经改变了formatter的值,但仍然是thread-2默认格式化程序与初始化值相同,其他线程也一样。

上面有一段代码用到了创建 ThreadLocal 变量的那段代码用到了 Java8 的知识,它等于下面这段代码,如果你写了下面这段代码的话,IDEA会提示你转换为Java8的格式(IDEA真的不错!)。因为ThreadLocal类在Java 8中扩展,使用一个新的方法withInitial(),将Supplier功能接口作为参数。

 private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue()
        {
            return new SimpleDateFormat("yyyyMMdd HHmm");
        }
    };

 类似资料:
  • 本文向大家介绍请介绍一下 ThreadPoolExecutor 类?相关面试题,主要包含被问及请介绍一下 ThreadPoolExecutor 类?时的应答技巧和注意事项,需要的朋友参考一下 线程池实现类 是 框架最核心的类。** ThreadPoolExecutor 类分析 类中提供的四个构造方法。我们来看最长的那个,其余三个都是在这个构造方法的基础上产生(其他几个构造方法说白点都是给定某些默认

  • 本文向大家介绍请简单介绍一下spring?相关面试题,主要包含被问及请简单介绍一下spring?时的应答技巧和注意事项,需要的朋友参考一下 考察点:spring 参考回答: Spring是一个轻量级框架,可以一站式构建你的企业级应用。 Spring的模块大概分为6个。分别是: 1、Core Container(Spring的核心)【重要】 2、AOP(面向切面变成)【重要】 3、Messaging

  • 本文向大家介绍请介绍一下红黑树?相关面试题,主要包含被问及请介绍一下红黑树?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 红黑树(Red Black Tree)是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。 它虽然是复杂的,但它的最坏情况运行时

  • 本文向大家介绍请你介绍一下B+树?相关面试题,主要包含被问及请你介绍一下B+树?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: B+是一种多路搜索树,主要为磁盘或其他直接存取辅助设备而设计的一种平衡查找树,在B+树中,每个节点的可以有多个孩子,并且按照关键字大小有序排列。所有记录节点都是按照键值的大小顺序存放在同一层的叶节点中。相比B树,其具有以下几个特点: 每个节点上的指针上限为2d而不

  • 本文向大家介绍介绍一下auc?相关面试题,主要包含被问及介绍一下auc?时的应答技巧和注意事项,需要的朋友参考一下 介绍auc,那么就介绍ROC,auc反映的是从样本集中抽出样本,预测这个样本是正例的概率比预测这个样本是反例的概率大的概率,做法是由于每种样本出现的概率已知,将其由小到大进行排序,依次作为截断概率,小于该概率预测为负例,大于该概率预测为正例,这样每个样本都有一个预测值,可以计算出样本

  • 本文向大家介绍请介绍一下HTTP协议(特征)?相关面试题,主要包含被问及请介绍一下HTTP协议(特征)?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完