ThreadLocal是什么

早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。

使用这个工具类可以很简洁地编写出优美的多线程程序。

当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,

所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。

所以,在Java中编写线程局部变量的代码相对来说要笨拙一些,因此造成线程局部变量没有在Java开发者中得到很好的普及。

ThreadLocal的接口方法

ThreadLocal类接口很简单,只有4个方法,我们先来了解一下:

  • void set(Object value)设置当前线程的线程局部变量的值。
  • public Object get()该方法返回当前线程所对应的线程局部变量。
  • public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
  • protected Object initialValue()返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。

  

在JDK5.0中,ThreadLocal已经支持泛型,该类的类名已经变为ThreadLocal<T>。API方法也相应进行了调整,

新版本的API方法分别是void set(T value)、T get()以及T initialValue()。

 下面将用一段代码展示ThreadLocal类的功能

package com.cary.base.thread;

import java.util.Random;

/**
* ThreadLocal测试
*
* @author cary
* @date 2015-8-24-下午6:06:01
* @version 1.0.0
*/
public class ThreadLocalTest {
private static ThreadLocal<Integer> x = new ThreadLocal<Integer>(); public static void main(String[] args) {
for (int i = ; i < ; i++) {
new Thread(new Runnable() {
public void run() {
int data = new Random().nextInt();
System.out.println(Thread.currentThread().getName()
+ " has put data :" + data);
x.set(data); new A().get();
new B().get();
}
}).start();
}
} /**
* 获取数据
*
* @author cary
* @date 2015-8-24-下午6:05:27
* @version 1.0.0
*/
static class A {
public void get() {
int data = x.get();
System.out.println("A from " + Thread.currentThread().getName()
+ " get data :" + data); }
} /**
* 获取数据
*
* @author cary
* @date 2015-8-24-下午6:05:44
* @version 1.0.0
*/
static class B {
public void get() {
int data = x.get();
System.out.println("B from " + Thread.currentThread().getName()
+ " get data :" + data); }
}
}

运行结果:

Thread- has put data :-
Thread- has put data :-
A from Thread- get data :-
A from Thread- get data :-
B from Thread- get data :-
B from Thread- get data :-

可以看到每个线程get()到的都是自己set()进去的值

我们写程序过程中经常有这样的代码

    private final static ThreadLocal<SystemUser> userThreadLocal = new ThreadLocal<SystemUser>();

    @Autowired
private SystemLogService systemLogService; /**
* 设置当前用户
*
* @author cary
* @param user
*/
public void setCurrentSystemUser(SystemUser user) {
userThreadLocal.set(user);
}
/**
* 从本地线程中取当前用户
*
* @author cary
* @return 系统用户
*/
public SystemUser getCurrentSystemUser() {
SystemUser user = userThreadLocal.get();
if (null == user) {
user = (SystemUser) SecurityUtils.getSubject().getPrincipal();
} return user;
}

小结:

ThreadLocal是解决线程安全问题一个很好的思路,它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。

在很多情况下,ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。

java多线程详解(5)-Threadlocal用法的更多相关文章

  1. Java 多线程详解(四)------生产者和消费者

    Java 多线程详解(一)------概念的引入:http://www.cnblogs.com/ysocean/p/6882988.html Java 多线程详解(二)------如何创建进程和线程: ...

  2. Java多线程详解(二)

    评论区留下邮箱可获得<Java多线程设计模式详解> 转载请指明来源 1)后台线程 后台线程是为其他线程服务的一种线程,像JVM的垃圾回收线程就是一种后台线程.后台线程总是等到非后台线程死亡 ...

  3. Java多线程详解

    Java线程:概念与原理 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程 ...

  4. java多线程详解(6)-线程间的通信wait及notify方法

    Java多线程间的通信 本文提纲 一. 线程的几种状态 二. 线程间的相互作用 三.实例代码分析 一. 线程的几种状态 线程有四种状态,任何一个线程肯定处于这四种状态中的一种:(1). 产生(New) ...

  5. Java 多线程详解(一)------概念的引入

    这是讲解 Java 多线程的第一章,我们在进入讲解之前,需要对以下几个概念有所了解. 1.并发和并行 并行:指两个或多个时间在同一时刻发生(同时发生): 并发:指两个或多个事件在一个时间段内发生. 在 ...

  6. 原创Java多线程详解(一)

    只看书不实践是不行的.来实践一下~~~~~~(引用请指明来源) 先看看百科对多线程的介绍 多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的 ...

  7. java多线程详解(8)-volatile,Atomic比较

    在变成过程中我们需要保证变量的线程安全,在java中除了使用锁机制或者Threadlocal等保证线程安全,还提供了 java.util.concurrent.atomic.Atomic*(如Atom ...

  8. java多线程详解(3)-线程的互斥与同步

    前言:前一篇文章主要描述了多线程中访成员变量与局部变量问题,我们知道访成员变量有线程安全问题,在多线程程序中 我们可以通过使用synchronized关键字完成线程的同步,能够解决部分线程安全问题 在 ...

  9. Java多线程详解(转载)

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用 ...

随机推荐

  1. 2015-08-26: GCC编译选项(转载)

    gcc提供了大量的警告选项,对代码中可能存在的问题提出警告,通常可以使用-Wall来开启以下警告:           -Waddress -Warray-bounds (only with -O2) ...

  2. NHibernate系列文章二十七:NHibernate Mapping之Fluent Mapping基础(附程序下载)

    摘要 从这一节起,介绍NHibernate Mapping的内容.前面文章都是使用的NHibernate XML Mapping.NHibernate XML Mapping是NHibernate最早 ...

  3. jQuery学习笔记(在js中增加、删除及定位控件的操作)

    代码内容很多都是从amazeui直接copy过来的,先声明,请不要说在下抄袭- - <!-------------------- HTML代码 ----------------------> ...

  4. RunTime的简单使用

    Runtime也就是运行时,是苹果官方提供的一套C语音库,那有什么作用呢?简单的来说,Runtime可以做很多的底层操作,比如说访问隐藏的一些成员变量,成员方法,当然包括了私有的成员变量,成员方法. ...

  5. Theme皮肤文件(json解析、多文件管理)

    一  官方教程 http://developer.egret.com/cn/github/egret-docs/extension/EUI/skin/theme/index.html 二 thm主题文 ...

  6. Neural Network学习(二)Universal approximator :前向神经网络

    1. 概述 前面我们已经介绍了最早的神经网络:感知机.感知机一个非常致命的缺点是由于它的线性结构,其只能做线性预测(甚至无法解决回归问题),这也是其在当时广为诟病的一个点. 虽然感知机无法解决非线性问 ...

  7. CSS3基础03(3D②) 求粉丝

    3 D (3.1)rotateY 围绕着Y轴进行旋转 (1)正数是(站在右边推),负数是(站在左边推) (2.1)定义元素背过去是否可见 backface-visibility: visible|hi ...

  8. 9.8 js进阶总结3

    DOM文档对象模型 DOM(document object model)文档对象模型,它定义了操作文档对象的接口. DOM 把一份html文档表示为一棵家谱树,使用parent(父),child(子) ...

  9. subversion(SVN)常规使用

    语法: svn <subcommand> [options] [args]      使用“svn help <subcommand>” 显示子命令的帮助信息.      使用 ...

  10. C#与Java的比较

    C#与Java的比较 写完后得知维基百科里有更加全面得多的比较: http://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java NET(C#) ...