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日

相关文章

  • asp.net core应用docke部署到centos7的全过程

    将Asp.Net Core应用程序部署到CentOS 7的完整攻略 在本攻略中,我们将详细讲解如何将Asp.Net Core应用程序部署到CentOS 7,并提供两个示例说明。 安装Docker:首先,我们需要在CentOS 7上安装Docker。我们可以使用以下命令来安装Docker: sudo yum install docker 安装Docker Co…

    C# 2023年5月16日
    00
  • 浅谈ASP.NET Core 中间件详解及项目实战

    ASP.NET Core 中间件是一种处理HTTP请求和响应的机制。中间件可以在请求到达控制器之前或响应返回给客户端之前执行一些操作。本文将详细讲解ASP.NET Core中间件的使用方法及项目实战。 什么是ASP.NET Core中间件? ASP.NET Core中间件是一种处理HTTP请求和响应的机制。中间件可以在请求到达控制器之前或响应返回给客户端之前…

    C# 2023年5月16日
    00
  • C#微信开发之自定义菜单管理

    C#微信开发之自定义菜单管理 简介 自定义菜单是公众号开发中最基本的功能之一,通过自定义菜单可以为用户提供更便捷的交互方式。本文将详细讲解使用C#开发微信自定义菜单的流程和方法。 准备工作 使用C#开发微信自定义菜单需要先完成以下准备工作: 成为微信公众号的开发者,开通公众号的开发权限。 在微信公众平台申请获得appid和appsecret两个关键信息。 在…

    C# 2023年5月31日
    00
  • Unity3D UGUI特效之Image高斯模糊效果

    下面我将详细讲解“Unity3D UGUI特效之Image高斯模糊效果”的完整攻略。 1. 什么是高斯模糊? 高斯模糊是一种图像处理算法,是对图像进行模糊处理的一种方法,模糊程度随着处理程度的加深而不断加深,可以在一定程度上使图像变得更加柔和,视觉效果更加温和自然。 2. Unity3D中实现高斯模糊的方法:Shader实现 在Unity3D中,我们可以通过…

    C# 2023年6月3日
    00
  • C#保存上传来的图片示例代码

    C#保存上传来的图片是一项常见的操作,下面是一个完整的攻略说明: 1.前置条件 在进行C#保存上传来的图片的操作时,首先我们需要创建一个ASP.NET Web应用程序。创建完成后,我们需要在Web.config配置文件中设置文件上传的相关参数: <system.web> <httpRuntime maxRequestLength=&quot…

    C# 2023年6月1日
    00
  • C#多线程学习之Thread、ThreadPool、Task、Parallel四者区别

    C#多线程学习之Thread、ThreadPool、Task、Parallel四者区别 1. 简介 C#是一门支持多线程的语言,它提供了几种不同的方式来实现多线程编程。本文将介绍C#中的Thread、ThreadPool、Task、Parallel四种方式,并解释它们之间的区别。 2. Thread Thread是一个代表执行线程的对象,在C#中使用Thre…

    C# 2023年5月15日
    00
  • C#将HashTable中键列表或值列表复制到一维数组的方法

    要将HashTable中的键列表或值列表复制到一维数组中,可以使用CopyKeys()或CopyValues()方法。这两个方法返回一个数组,该数组包含Hash表中所有键或值。 具体步骤如下: 1. 创建一个HashTable对象并赋值 // 创建一个HashTable对象 Hashtable ht = new Hashtable(); // 赋值 ht.A…

    C# 2023年6月7日
    00
  • C# String.Substring()方法: 检索此字符串中子字符串的指定部分

    String.Substring() 可以用于获取字符串的子串,它的作用是返回一个新的字符串,该字符串是原字符串的一个子集。 使用方法 String.Substring()的使用方法如下: string.Substring(int startIndex) string.Substring(int startIndex, int length) 其中,star…

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