面试官:解释一下 ThreadLocal 核心原理

在并发编程中,除了可以使用锁机制来保证线程安全,JDK 中还提供了 ThreadLocal 类来保证多个线程能够安全访问共享变量。本章简单介绍 ThreadLocal 的核心原理。

本文涉及的知识点如下。

—ThreadLocal 的基本概念。

—ThreadLocal 的使用案例。

—ThreadLocal 的核心原理。

—ThreadLocal 变量的继承性。

—InheritableThreadLocal 的使用案例。

—InheritableThreadLocal 的核心原理。

ThreadLocal 的基本概念

在并发编程中,多个线程同时访问同一个共享变量,可能会出现线程安全的问题。为了保证在多线程环境下访问共享变量的安全性,通常会在访问共享变量的时候加锁,以实现线程同步的效果。

使用同步锁机制保证多线程访问共享变量的安全性的原理如图 14-1 所示。该机制能够保证同一时刻只有一个线程访问共享变量,从而确保在多线程环境下访问共享变量的安全性。

另外,为了更加灵活地确保线程的安全性,JDK 中提供了一个 ThreadLocal 类,ThreadLocal 类能够支持本地变量。在使用 ThreadLocal 类访问共享变量时,会在每个线程的本地内存中都存储一份这个共享变量的副本。在多个线程同时对这个共享变量进行读写操作时,实际上操作的是本地内存中的变量副本,多个线程之间互不干扰,从而避免了线程安全的问题。使用 ThreadLocal 访问共享变量的示意图如图 14-2 所示。

ThreadLocal 的使用案例

本节主要实现两个通过 ThreadLocal 操作线程本地变量的案例,以此加深读者对 ThreadLocal 的理解。

案例一的主要实现逻辑:在案例程序中分别创建名称为 Thread-A 和 Thread-B 的两个线程, 在 Thread-A 线程和 Thread-B 线程的 run()方法中通过 ThreadLocal 保存本地变量,随后打印 Thread-A 线程和 Thread-B 线程中保存的本地变量。最后,启动 Thread-A 线程和 Thread-B 线程。

案例一的核心代码如下。

/**
*@author binghe
*@version 1.0.0
*@description ThreadLocal 案例程序
*/
public class ThreadLocalTest {

private static final ThreadLocal<String> THREAD_LOCAL = new 
ThreadLocal<String>();

public static void main(String[] 
args){ Thread threadA = new 
Thread(()->{
THREAD_LOCAL.set("ThreadA: " + Thread.currentThread().getName());
 System.out.println(Thread.currentThread().getName() + "本地变量中的值为: "
+ THREAD_LOCAL.get());
}, "Thread-A");

Thread threadB = new Thread(()->{
THREAD_LOCAL.set("ThreadB: " + Thread.currentThread().getName());
 System.out.println(Thread.currentThread().getName() + "本地变量中的值为: "
+ THREAD_LOCAL.get());
}, "Thread-B");

threadA.start();
 threadB.start();
}
}

运行上述代码,输出结果如下。

Thread-A 本地变量中的值为: ThreadA: Thread-A

Thread-B 本地变量中的值为: ThreadB: Thread-B

从输出结果可以看出,Thread-A 线程和 Thread-B 线程通过 ThreadLocal 保存了本地变量, 并未正确打印出结果。

案例二的主要实现逻辑:在案例一的基础上为 Thread-B 线程增加删除 ThreadLocal 中保存的本地变量的操作,随后打印结果来证明删除 Thread-B 线程中的本地变量不会影响 Thread-A 线程中的本地变量。

案例二的核心代码如下。

/**
*@author binghe
*@version 1.0.0
* @description ThreadLocal 案例程序
*/
public class ThreadLocalTest {
private static final ThreadLocal<String> THREAD_LOCAL = new 
ThreadLocal<String>();

public static void main(String[] 
args){ Thread threadA = new 
Thread(()->{
THREAD_LOCAL.set("ThreadA: " + Thread.currentThread().getName()); 
System.out.println(Thread.currentThread().getName() + "本地变量中的值为: "
+ THREAD_LOCAL.get());
System.out.println(Thread.currentThread().getName() + "未删除本地变量,本地变量中的值为: " + THREA
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值