一、线程私有

在多线程情况下,对于一个共享的数据可能会产生线程安全问题。最简单的解决办法就是堆访问共享数据的时候加锁,但我们知道加锁是很影响效率的,尤其是像数据库连接这样耗费资源较多的情况下,加锁就意味着你的程序无法提供高效的服务。

那么我们会这样思考,是否每个线程能够自己独有一份数据呢?这样线程之间不会相互影响,也就不存在数据共享的线程安全问题了,ThreadLocal类便是对于这样的需求的具体实现类。

JDK文档:http://tool.oschina.net/uploads/apidocs/jdk-zh/java/lang/ThreadLocal.html

二、ThreadLocal类

ThreadLocal类直接继承与Object类,它存在于java.lang包下。

该类使得每个线程拥有自己的局部变量,该变量独立于变量的初始化副本,也就是说每个线程其实是持有着一份拷贝的副本,并不直接使用初始化数据。ThreadLocal的实例通常是private static 字段描述,线程私有的数据将在线程销毁以后随之清除。

构造方法:

ThreadLocal() // 创建一个线程本地变量。

方法摘要:

 T    get() // 返回此线程局部变量的当前线程副本中的值。
protected  T    initialValue() // 返回此线程局部变量的当前线程的“初始值”。
 void    remove() // 移除此线程局部变量当前线程的值。
 void    set(T value) // 将此线程局部变量的当前线程副本中的值设置为指定值

三、示例

public class ThreadLocalTest {
    private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            // 初始化值为1
            return 1;
        }
    };

    public static void main(String[] args) {
        System.out.println("主线程获取初始值副本:" + threadLocal.get());
        threadLocal.set(2); // 设置主线程副本值
        System.out.println("主线程获取副本新的值:" + threadLocal.get());
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("另起一个线程获取副本值:" + threadLocal.get());;
            }
        }).start();
        threadLocal.remove(); // 移除主线程的副本
        System.out.println("主线程重新获取副本的值:" + threadLocal.get());
    }
}

控制台打印:

主线程获取初始值副本:1
主线程获取副本新的值:2
另起一个线程获取副本值:1
主线程重新获取副本的值:1

从示例中我们看到:

主线程拷贝了一份初始值1,然后设置了初始值2,另起一个线程又从初始值中拷贝了1,与主线程设置的值无关。

当主线程移除了副本以后,再次调用get()方法则将再次从初始值中拷贝。

注意:如果没有重写initialValue,那么get()方法将取到null值。

五、线程本地ThreadLocal的更多相关文章

  1. 深入理解线程本地变量ThreadLocal

    ThreadLocal理解: 假设在多线程并发环境中.一个可变对象涉及到共享与竞争,那么该可变对象就一定会涉及到线程间同步操作,这是多线程并发问题. 否则该可变对象将作为线程私有对象,可通过Threa ...

  2. 线程本地变量ThreadLocal源码解读

      一.ThreadLocal基础知识 原始线程现状: 按照传统经验,如果某个对象是非线程安全的,在多线程环境下,对对象的访问必须采用synchronized进行线程同步.但是Spring中的各种模板 ...

  3. 线程本地变量ThreadLocal

    一.本地线程变量使用场景 并发应用的一个关键地方就是共享数据.如果你创建一个类对象,实现Runnable接口,然后多个Thread对象使用同样的Runnable对象,全部的线程都共享同样的属性.这意味 ...

  4. Atitit usrqbg1821 Tls 线程本地存储(ThreadLocal Storage 规范标准化草案解决方案ThreadStatic

    Atitit usrqbg1821 Tls 线程本地存储(ThreadLocal Storage 规范标准化草案解决方案ThreadStatic 1.1. ThreadLocal 设计模式1 1.2. ...

  5. 线程本地变量ThreadLocal (耗时工具)

    线程本地变量类 package king; import java.util.ArrayList; import java.util.List; import java.util.Map; impor ...

  6. ThreadLocal 线程本地变量 及 源码分析

    ■ ThreadLocal 定义 ThreadLocal通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量 ...

  7. 线程本地变量ThreadLocal (耗时工具)【原】

    线程本地变量类 package king; import java.util.ArrayList; import java.util.List; import java.util.Map; impor ...

  8. Java并发(二十):线程本地变量ThreadLocal

    ThreadLocal是一个本地线程副本变量工具类. 主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不同的 ...

  9. ThreadLocal(线程本地存储)

    1. ThreadLocal,即线程本地变量或线程本地存储. threadlocal的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的 ...

随机推荐

  1. C - Oil Deposits(dfs)

    点击打开链接 Oil Deposits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe ...

  2. “全栈2019”Java多线程第十五章:当后台线程遇到finally

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  3. [agc006f] Blackout 神题

    Description ​ 给你一个NN行NN列的网格,第ii行第jj列的格子用(i,j)(i,j)表示 一开始的时候有MM个格子被涂成黑色,其他的格子都是白色,具体一点,涂成黑色的格子为(a1,b1 ...

  4. static修饰的方法不能被重写可以被继承

    今天我们谈谈为什么抽象类中不能有静态的抽象方法以及static修饰的方法不能被重写可以被继承 1 static修饰的方法不能被重写可以被继承我们知道static修饰的方法为静态方法,可以直接使用类名. ...

  5. aspx代码审计-2

    今天和大家分享一下aspx网站的代码审计,漏洞类型为:未授权访问和任意文件下载. 本文作者:i春秋签约作家——非主流 今天看的源码文件就不共享给大家了,本文只作学习只用. 还是先看我们的文件夹目录和d ...

  6. Lucene.Net+盘古分词器(详细介绍)

    本章阅读概要1.Lucenne.Net简介2.介绍盘古分词器3.Lucene.Net实例分析4.结束语(Demo下载)Lucene.Net简介 Lucene.net是Lucene的.net移植版本,是 ...

  7. php解析word,获得文档中的图片

    背景 前段时间在写一个功能:用原生php将获得word中的内容并导入到网站系统中.因为文档中存在公式,图片,表格等,因此写的比较麻烦. 思路 大体思路是先将word中格式为doc的文档转化为docx, ...

  8. 配置bootstrap环境

    bootstrap是一个优雅,灵活,可扩展的前端工具集,可搭建WEB页面的HTML,CSS,JavaScript工具集,最重要的是它的栅格系统. 这里不做更多的详细介绍具体可参照官方网站:http:/ ...

  9. python学习,day4:生成器

    1.生成器:只有在调用是才会生成相应的数据.(比较省内存,它只保留当时生成的.而列表会保存整个列表) a = [i*2 for i in range(10)] #列表生成式 print(a) 这样会把 ...

  10. Java NIO学习与记录(五): 操作系统的I/O模型

    操作系统的I/O模型 在开始介绍NIO Reactor模式之前,先来介绍下操作系统的五种I/O模型,了解了这些模型,对理解java nio会有不小的帮助. 先来看下一个服务端处理一次网络请求的流程图: ...