一、线程私有

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

那么我们会这样思考,是否每个线程能够自己独有一份数据呢?这样线程之间不会相互影响,也就不存在数据共享的线程安全问题了,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. Tomcat绿色版启动"startup.bat"一闪问题的解决方法!

    进入DOS窗口,运行"startup.bat",会出现错误提示,我是win7 64位,提示“JRE_HOME”设置不正确.于是进入环境变量配置,设置“JRE_HOME”项,随后保存 ...

  2. ZJOI2019 游记

    Day -2 入住酒店,跟 Sooke 一个房间 酒店还是很好的呢 然后就是颓废 Sooke 和 zxy,ljx,lyt,xx 一起打 lol,我孤独的打着坦克和 MC 然后复习了一下板子 Day - ...

  3. [ActionScript 3.0] 幻灯片效果实例

    package com.fylibs.components.effects { import com.fylibs.utils.LoaderQueues; import com.tweener.tra ...

  4. package.json和bower的参数解释

    package.json和bower的参数解释   一.package.json解释: package.json是用来声明项目中使用的模块,这样新的环境部署时,只要在package.json文件所在的 ...

  5. SpringQuartz定时任务cronExpression配置

    <!-- 每一个小时跑一次--> <property name="cronExpression"> <value>0 0 0/1 * * ?&l ...

  6. [原创]Laravel 的缓存源码解析

    目录 前言 使用 源码 Cache Facade CacheManager Repository Store 前言 Laravel 支持多种缓存系统, 并提供了统一的api接口. (Laravel 5 ...

  7. 对于一些seo查询网站的整理

    个人在查找网站seo问题时所使用的一些网站整理以及一些注意事项(同时感谢在处理问题过程中给予帮助的小伙伴们): 1.seo综合查询    (爱站网/站长工具)这俩工具的计算规则不相同所以计算结果出来也 ...

  8. web环境中的spring MVC

    1. web.xml文件的简单详解 在web环境中, spring MVC是建立在IOC容器的基础上,要了解spring mvc,首先要了解Spring IOC容器是如何在web环境中被载入并起作用的 ...

  9. 编程开发之--java多线程学习总结(2)同步代码块

    1.第一种解决办法:同步代码块,关键字synchronized package com.lfy.ThreadsSynchronize; /** * 1.使用同步代码块 * 语法: synchroniz ...

  10. Visual Studio进行负载测试,RIG和负载测试术语- Part II

    对于一个多用户的应用程序,性能是非常重要的.性能不仅是执行的速度,它包括负载和并发方面.Visual Studio是可以用于性能测试的工具之一.Visual Studio Test版或Visual S ...