ThreadLocal 在上下文传值场景实践源码

ThreadLocal 是 Java 中常用的多线程编程技术之一,它可以在多个线程环境中保存并传递数据,将数据与线程绑定在一起,实现线程的局部变量。在一些上下文传值的场景中,ThreadLocal 可以较为方便的实现参数的传递。接下来,本文将详细讲解 ThreadLocal 在上下文传值场景实践源码的完整攻略。

什么是 ThreadLocal

ThreadLocal 是一个与线程绑定的变量,它可以在不同线程中保存和取出相应的值,即每个 ThreadLocal 对象都可以在某个线程中存储一个值。在多个线程环境下,每个线程可能都需要访问变量并进行修改,但是线程之间互相干扰会导致数据不一致,ThreadLocal 就是为了解决这一问题而存在的。

在 Java 中,ThreadLocal 可以实现变量的线程局部化,保证每个线程中有自己的变量副本,避免线程干扰,实现了线程间数据的隔离。ThreadLocal 常用于应用中跨越多个组件、层或方法的上下文传值场景中,就可以避免传参的烦扰。单例线程池异步处理的时候,经常需要在线程调用之前或结束时传递一些值。

ThreadLocal 用法示例

下面让我们通过两个示例来说明 ThreadLocal 的用法,先定义一个简单的 Request 类,模拟一个请求。

public class Request {

    private final String name;

    public Request(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

示例一:通过 ThreadLocal 将 Request 对象在多个方法中传递

假设现在有一个三层的方法嵌套:firstMethod -> secondMethod -> thirdMethod,需要将一个 Request 对象在这三个方法中传递。此时可以使用 ThreadLocal,将 Request 对象绑定到当前线程中。

public class ThreadLocalExample1 {

    private static final ThreadLocal<Request> REQUEST_THREAD_LOCAL = new ThreadLocal<>();

    public static void main(String[] args) {
        Request request = new Request("test");
        REQUEST_THREAD_LOCAL.set(request);
        firstMethod();
    }

    public static void firstMethod() {
        Request request = REQUEST_THREAD_LOCAL.get();
        System.out.println("firstMethod get request: " + request.getName());
        secondMethod();
    }

    public static void secondMethod() {
        Request request = REQUEST_THREAD_LOCAL.get();
        System.out.println("secondMethod get request: " + request.getName());
        thirdMethod();
    }

    public static void thirdMethod() {
        Request request = REQUEST_THREAD_LOCAL.get();
        System.out.println("thirdMethod get request: " + request.getName());
    }
}

运行结果如下:

firstMethod get request: test
secondMethod get request: test
thirdMethod get request: test

从结果可以看出,通过 ThreadLocal 可以实现变量在多个方法中的传递,非常方便。

示例二:在多线程环境中使用 ThreadLocal

假如现在有 2 个线程,需要对一个计数器进行操作,每个线程自己维护计数。此时可以使用 ThreadLocal,将计数器的值绑定到当前线程中。

public class ThreadLocalExample2 {

    private static final ThreadLocal<Integer> COUNTER = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return 0;
        }
    };

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            int counter = COUNTER.get();
            for (int i = 0; i < 5; i++) {
                counter++;
                COUNTER.set(counter);
                System.out.println(Thread.currentThread().getName() + " - " + counter);
            }
        });

        Thread t2 = new Thread(() -> {
            int counter = COUNTER.get();
            for (int i = 0; i < 5; i++) {
                counter++;
                COUNTER.set(counter);
                System.out.println(Thread.currentThread().getName() + " - " + counter);
            }
        });

        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}

运行结果如下:

Thread-0 - 1
Thread-0 - 2
Thread-0 - 3
Thread-0 - 4
Thread-0 - 5
Thread-1 - 1
Thread-1 - 2
Thread-1 - 3
Thread-1 - 4
Thread-1 - 5

从结果可以看出,每个线程自己维护自己的计数器,ThreadLocal 实现了在多线程环境下的计数器对象的隔离。

结语

本文详细讲解了 ThreadLocal 在上下文传值场景实践源码的完整攻略,并提供了两个示例,希望可以帮助到大家。ThreadLocal 是一个非常实用的多线程编程技术,可以帮助避免线程干扰的问题,实现线程间数据隔离。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:ThreadLocal 在上下文传值场景实践源码 - Python技术站

(0)
上一篇 2023年6月7日
下一篇 2023年6月7日

相关文章

  • C#把数组中的某个元素取出来放到第一个位置的实现方法

    C#中可以使用数组索引来访问数组元素。要把数组中的某个元素取出来放到第一个位置,我们可以使用以下步骤: 使用数组索引找到要提取的元素。 使用for循环或Array.Copy方法将剩余元素向后移动一个位置。 把提取元素放到数组的第一个位置。 下面是两个示例,展示了如何实现这个过程: 示例一:使用for循环实现 int[] arr = { 1, 2, 3, 4,…

    C# 2023年6月1日
    00
  • .Net 对于PDF生成以及各种转换的操作

    以下是关于”.Net 对于PDF生成以及各种转换的操作”的完整攻略。 准备工作 在开始操作之前,需要准备以下工具: Visual Studio,用于编写 .Net 程序。 iTextSharp,用于生成 PDF 文件。 Ghostscript,用于将 PDF 文件转换为图片或其他格式文件。 生成 PDF 文件 1. 安装 iTextSharp 在 Visua…

    C# 2023年6月3日
    00
  • C#开发纽曼USB来电小秘书客户端总结

    C#开发纽曼USB来电小秘书客户端总结 本文基于C#语言开发一个针对Windows系统的小型应用程序——纽曼USB来电小秘书客户端。该程序能够通过识别USB来电设备实现来电提醒、号码白名单管理等功能。 技术要点 本程序使用的技术栈主要包括: C#语言 .NET框架 FTDI USB驱动 WPF UI框架 步骤 1. 准备工作 在开始开发之前,我们需要准备好以…

    C# 2023年6月7日
    00
  • IIS7.5 Error Code 0x8007007e HTTP 错误 500.19的解决方法

    IIS7.5ErrorCode0x8007007eHTTP错误500.19是一种常见的IIS错误,通常是由于配置文件中的错误或缺失文件引起的。本文将介绍如何解决这个问题,并提供两个示例来演示如何使用这些技术。 解决IIS7.5ErrorCode0x8007007eHTTP错误500.19的方法 以下是解决IIS7.5ErrorCode0x8007007eHT…

    C# 2023年5月15日
    00
  • Unity3D获取当前键盘按键及Unity3D鼠标、键盘的基本操作

    Unity3D获取当前键盘按键: Unity3D中获取当前键盘按键可以通过Input.GetKey(),Input.GetKeyDown(),Input.GetKeyUp()三个函数来实现。 其中,Input.GetKeyDown()用于检测用户是否按下某个键,如果是则返回true,否则返回false。而Input.GetKeyUp()用于检测用户是否松开某…

    C# 2023年6月3日
    00
  • C# Winform实现石头剪刀布游戏

    下面我将详细讲解“C#Winform实现石头剪刀布游戏”的完整攻略。 准备工作 首先,我们需要创建一个Winform应用程序,然后在窗体中添加三个按钮,分别代表石头、剪刀、布。接着,我们需要编写代码,实现石头剪刀布的逻辑。 实现过程 1.定义变量 首先,我们需要在代码中定义三个变量,分别代表石头、剪刀和布。代码如下: int rock = 1; int sc…

    C# 2023年5月15日
    00
  • C#中把DataTable、Dataset转Json数据

    转化 DataTable 或者 Dataset 为 Json 数据可以借助于第三方库,比如 Newtonsoft.Json 库。以下是具体的示例攻略: 1. 使用 Newtonsoft.Json 转换单个 DataTable 在 Visual Studio 等 IDE 中,在项目中添加 Newtonsoft.Json 库,或者通过 NuGet 安装 给 Da…

    C# 2023年5月31日
    00
  • C#实现中文验证码的示例代码

    下面就为您详细讲解”C#实现中文验证码的示例代码”的完整攻略,其中包含两个示例说明。 1. 前置知识 在实现中文验证码之前,需要先了解以下知识: C#基础编程知识 图形绘制基础 验证码的概念和生成方式 中文字体库的使用 2. 实现过程 2.1 创建项目和添加引用 首先,我们需要创建一个控制台应用程序的项目,然后在该项目中添加System.Drawing和Sy…

    C# 2023年6月7日
    00
合作推广
合作推广
分享本页
返回顶部