当前位置:   article > 正文

Java线程上下文-ThreadLocal的那些事_java中的上下文是不是就是线程变量

java中的上下文是不是就是线程变量

一、概述

ThreadLocal: 通常被称作线程本地变量或者线程本地存储。其含义是ThreadLocal为变量在每个线程中都创建一个副本,则每个线程可以访问自身内部的副本变量。
概念总是抽象而且晦涩的,我们从两个例子说起。

1、对象间/方法间跨层传递

如下图,有个多层调用的情况,如果我们需要传递某个中间结果在这几层调用关系之间,应该怎么处理呢?
多层调用

  • 一种简单的思路是,把每个函数新增一个参数,然后依次传递下去。但是,如果参数过多,或者某一个函数为公共函数,不允许我们随意添加参数的话,那该怎么处理呢?
  • 另一种思路,设置一个单例类,实时保存该数据。实存实取。也能保证其在各个函数之间的传递。但是,如果是多线程操作怎么保证单例数据不被污染?
    假设,我们在A.fun1()之中将数据保存在单例类中,然后在之后的其他函数中操作该数据。如果是多线程的环境,如果同时有多个线程同时操作入口函数A.fun1(),则单例保存的数据则会被污染。
  • 还有一种思路,就是使用ThreadLocal为该数据在每个线程中都创建一个副本,则线程之间则不会互相影响。如下代码,通过ThreadLocal,我们可以使数据在对象间/方法间进行传递。
public class ThreadLocalDemo {
    private ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    private void fun1() {
        threadLocal.set(System.nanoTime());
        System.out.println("fun1:" + threadLocal.get());
        fun2();
    }

    private void fun2() {
        System.out.println("fun2:" + threadLocal.get());
        fun3();
    }

    private void fun3() {
        System.out.println("fun3:" + threadLocal.get());
        threadLocal.remove();
    }

    public static void main(String[] args) {
        ThreadLocalDemo demo = new ThreadLocalDemo();
        demo.fun1();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

2、线程间的数据隔离

如果需要将一个单线程的应用移植到到多线程的环境下,就需要将共享的一些全局变量转换为ThreadLocal对象;这相当于ThreadLocal为每个线程都创建了一个该全局变量的副本。保证了其线程安全性。

但是,TheadLocal并不是解决高并发下共享资源的方式。大多数情况下,ThreadLocal存储的是一个new的新对象。但是如果其存储一个对象的引用,也会面临资源竞争的情况。

  • 例子1:ThreadLocal与Synchronized区别
    好多人都说ThreadLocal和Synchroized一样,实现了线程同步。那我们看个例子。
    假设有一个static int a = 0;,共有5个线程对其进行++操作,保险起见,我们对++进行加锁(Sync)。这样在执行完之后,a == 5,毫无疑问。
    同样的,我们起初使用ThreadLocal保存a =
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号