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#控制台输出进度和百分比的实例代码”的完整攻略。 1. 实现思路 在C#中,我们可以通过控制台输出一些信息来显示进度和百分比。一般情况下,我们需要用到以下几个关键步骤: 获取总的任务量 对任务进行遍历或者处理,并计算完成进度 输出进度和百分比信息 2. 实例代码1 下面我将演示一个简单的示例代码,其中我们通过遍历一个集合来计算进度和百分比…

    C# 2023年6月7日
    00
  • C# DataTable使用方法详解

    C# DataTable使用方法详解 什么是DataTable DataTable是一个用于表示和操作内存中表格数据的类,它模拟了数据库中的数据表,包含了一行一列的数据,每列都有唯一的名称和类型,并且可以通过对DataTable进行填充、查询、排序、筛选等操作,来完成数据的管理和处理。 如何创建DataTable 可以通过以下步骤来创建DataTable: …

    C# 2023年6月1日
    00
  • C#根据IP地址查询所属地区实例详解

    C#根据IP地址查询所属地区实例详解 前言 在实际的web开发中,我们经常会使用到IP地址的查询功能。本文主要介绍如何使用C#根据IP地址查询所属地区的具体实现过程。 步骤 1. 获取IP地址 我们可以使用ASP.NET中的Request对象获取用户IP地址,示例代码如下: string userIP = Request.UserHostAddress; 2…

    C# 2023年6月1日
    00
  • 基于NVelocity的几种内容生成方式汇总

    NVelocity是一种基于Java的模板引擎,它可以将模板和数据合并生成最终的文本内容。在使用NVelocity时,可以采用多种方式生成内容,包括使用模板文件、使用字符串模板、使用代码生成等。本文将提供基于NVelocity的几种内容生成方式的完整攻略,包括安装NVelocity、创建模板文件、使用字符串模板、使用代码生成等。同时,本文还提供两个示例,演示…

    C# 2023年5月15日
    00
  • c#字符长度查询代码

    下面是关于C#字符长度查询代码的完整攻略: 1. 字符串长度及字符长度的定义 首先,需要明确字符串长度和字符长度的定义: 字符串长度:指的是一个字符串所包含的字符个数。 字符长度:指的是不同编码对应的字符所占用的字节数。 举个例子,假设有以下字符串: "abc你好" 这个字符串的长度是6,因为它包含了6个字符;但是它的字符长度则取决于所使…

    C# 2023年6月1日
    00
  • C# 数据类型转换

    关于C#数据类型转换,我们可以从以下几个方面进行讲解。 数据类型转换 在 C# 中,数据类型可以分为值类型和引用类型。值类型中又可分为基本数据类型和结构体类型。而在操作中,我们有时需要将数据从一种类型转换为另一种类型。 C# 中的数据类型转换可以分为以下几种: 隐式类型转换:C#中一些类型间的转换是隐含的,也就是说不需要特殊的操作就能完成,例如将short类…

    C# 2023年5月15日
    00
  • C#代码实现扑克牌排序的几种方式

    C#代码实现扑克牌排序的几种方式 1. 排序算法简介 排序算法是计算机程序设计中重要的算法之一,其目的是把一组无序的数据按照一定的顺序排列。排序算法在许多领域中都有广泛的应用,如在数据库中对数据进行排序,对数据结构中的元素进行排序等。 目前常用的排序算法有插入排序、冒泡排序、选择排序、快速排序、归并排序等。其中,插入排序、冒泡排序、选择排序是比较基础和简单的…

    C# 2023年6月7日
    00
  • C# List生成Txt文档并且读取Txt文档封装List

    生成Txt文档并且读取Txt文档封装List 是一个非常常见的需求,一般使用C#中的File和List类就可以很容易地完成。 以下是具体的步骤: 1. 创建List对象 首先,在C#中创建一个List对象来存储要写入到文本文件中的元素,我们可以通过new关键字来创建一个字符串类型的List对象,例如: List<string> list = ne…

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