java多线程详解(5)-Threadlocal用法
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用法的更多相关文章
- Java 多线程详解(四)------生产者和消费者
Java 多线程详解(一)------概念的引入:http://www.cnblogs.com/ysocean/p/6882988.html Java 多线程详解(二)------如何创建进程和线程: ...
- Java多线程详解(二)
评论区留下邮箱可获得<Java多线程设计模式详解> 转载请指明来源 1)后台线程 后台线程是为其他线程服务的一种线程,像JVM的垃圾回收线程就是一种后台线程.后台线程总是等到非后台线程死亡 ...
- Java多线程详解
Java线程:概念与原理 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程 ...
- java多线程详解(6)-线程间的通信wait及notify方法
Java多线程间的通信 本文提纲 一. 线程的几种状态 二. 线程间的相互作用 三.实例代码分析 一. 线程的几种状态 线程有四种状态,任何一个线程肯定处于这四种状态中的一种:(1). 产生(New) ...
- Java 多线程详解(一)------概念的引入
这是讲解 Java 多线程的第一章,我们在进入讲解之前,需要对以下几个概念有所了解. 1.并发和并行 并行:指两个或多个时间在同一时刻发生(同时发生): 并发:指两个或多个事件在一个时间段内发生. 在 ...
- 原创Java多线程详解(一)
只看书不实践是不行的.来实践一下~~~~~~(引用请指明来源) 先看看百科对多线程的介绍 多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的 ...
- java多线程详解(8)-volatile,Atomic比较
在变成过程中我们需要保证变量的线程安全,在java中除了使用锁机制或者Threadlocal等保证线程安全,还提供了 java.util.concurrent.atomic.Atomic*(如Atom ...
- java多线程详解(3)-线程的互斥与同步
前言:前一篇文章主要描述了多线程中访成员变量与局部变量问题,我们知道访成员变量有线程安全问题,在多线程程序中 我们可以通过使用synchronized关键字完成线程的同步,能够解决部分线程安全问题 在 ...
- Java多线程详解(转载)
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用 ...
随机推荐
- 安装mysql步骤
1.yum install lrzsz 安装上传功能2.查看系统是否装有MySql :rpm -qa | grep mysql3.查看系统Mysql位置 :whereis mysql4.卸载Mysq ...
- 初探VIM编辑器
初探VIM 引言---什么是Vim? 接触Linux这么久,想必对于一切皆文件的哲学思想已经不陌生了.因此,学习并掌握用一款Linux文本编辑器,对于玩转LInux来说,是很有必要的. vi编辑器是U ...
- 二叉树遍历(Binary Tree Traversal)
二叉树的递归遍历比较简单,这里说一下非递归遍历,以中序遍历为例子. 非递归遍历主要用到栈来协助进行.对于一个二叉树,首先根节点入栈,如果有左儿子,则继续入栈,重复直到最左边的儿子,这时候此节点值为要遍 ...
- 【转】MaxScript.Net接收本地端口的消息执行
MaxScript里开不了线程,但是可以用.Net的BackgroundWorker来做后台处理 BackgroundWorker Fn BackgroundTcpListenerDoWork the ...
- iOS原型模式
原型模式:大部分重复,只有一小部分不同的情况下,为了代码清晰和避免麻烦,用原型模式,会更方便一点 // 学生1 StudentModel *stu1 = [[StudentModel alloc] i ...
- 8天掌握EF的Code First开发系列之3 管理数据库创建,填充种子数据以及LINQ操作详解
本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LI ...
- oracle 触发器学习
触发器使用教程和命名规范 目 录触发器使用教程和命名规范 11,触发器简介 12,触发器示例 23,触发器语法和功能 34,例一:行级触发器之一 45,例二:行级触发器之二 46,例三:INSTEA ...
- linux学习8 第八章 权限管理
8.1 ACL权限 8.2 文件特殊权限 8.3 文件系统属性chattr权限 8.4 系统命令sudo权限 8.1 ACL权限 ACL权限简介与开启 查看与设定ACL权限 最大有效权限与删除ACL权 ...
- linux 学习 软件工具
_____secureCRT 远程通信工具 第二行第二个快速连接,输入主机名,即ip地址,和用户名,root .其它默认:端口22,协议ssh2,防火墙 none. 保存会话,连接.需要输入用户密码. ...
- 使用ZooKeeper实现软负载均衡(原理)
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,提供的功能包括配置维护.名字服务.分布式同步.组服务等. ZooKeeper会维护一个树形的数据结构,类似于Windows资源管理器 ...