五、线程本地ThreadLocal
一、线程私有
在多线程情况下,对于一个共享的数据可能会产生线程安全问题。最简单的解决办法就是堆访问共享数据的时候加锁,但我们知道加锁是很影响效率的,尤其是像数据库连接这样耗费资源较多的情况下,加锁就意味着你的程序无法提供高效的服务。
那么我们会这样思考,是否每个线程能够自己独有一份数据呢?这样线程之间不会相互影响,也就不存在数据共享的线程安全问题了,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的更多相关文章
- 深入理解线程本地变量ThreadLocal
ThreadLocal理解: 假设在多线程并发环境中.一个可变对象涉及到共享与竞争,那么该可变对象就一定会涉及到线程间同步操作,这是多线程并发问题. 否则该可变对象将作为线程私有对象,可通过Threa ...
- 线程本地变量ThreadLocal源码解读
一.ThreadLocal基础知识 原始线程现状: 按照传统经验,如果某个对象是非线程安全的,在多线程环境下,对对象的访问必须采用synchronized进行线程同步.但是Spring中的各种模板 ...
- 线程本地变量ThreadLocal
一.本地线程变量使用场景 并发应用的一个关键地方就是共享数据.如果你创建一个类对象,实现Runnable接口,然后多个Thread对象使用同样的Runnable对象,全部的线程都共享同样的属性.这意味 ...
- Atitit usrqbg1821 Tls 线程本地存储(ThreadLocal Storage 规范标准化草案解决方案ThreadStatic
Atitit usrqbg1821 Tls 线程本地存储(ThreadLocal Storage 规范标准化草案解决方案ThreadStatic 1.1. ThreadLocal 设计模式1 1.2. ...
- 线程本地变量ThreadLocal (耗时工具)
线程本地变量类 package king; import java.util.ArrayList; import java.util.List; import java.util.Map; impor ...
- ThreadLocal 线程本地变量 及 源码分析
■ ThreadLocal 定义 ThreadLocal通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量 ...
- 线程本地变量ThreadLocal (耗时工具)【原】
线程本地变量类 package king; import java.util.ArrayList; import java.util.List; import java.util.Map; impor ...
- Java并发(二十):线程本地变量ThreadLocal
ThreadLocal是一个本地线程副本变量工具类. 主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不同的 ...
- ThreadLocal(线程本地存储)
1. ThreadLocal,即线程本地变量或线程本地存储. threadlocal的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的 ...
随机推荐
- css3旋转动画
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- P4383 [八省联考2018]林克卡特树lct
题目链接 题意分析 一句话题意就是 : 让你选出\((k+1)\)条不相交的链 使得这些链的边权总和最大 (这些链可以是点) 我们考虑使用树形\(DP\) \(dp[i][j][0/1/2]\)表示以 ...
- L02-RHEL6.5环境中安装JDK1.8
注: 1.本文安装的是jdk1.8,采用rpm包的方式安装. 2.rpm安装方式默认会把jdk安装到/usr/java/jdk1.8xxx 路径上,若想将JDK安装到特定路径,需以源码方式安装,可参考 ...
- JavaScript DOM编程艺术 笔记(四)
DOM document object model(map) 家谱树---节点树 父 子 兄弟 元素节点 <div> 文本节点 内容 属性节点 value src getE ...
- 常用的re正则
常用的正则表达式: 用户名:/^[a-z0-9_-]{3,16}$/ 密码:/^[a-z0-9_-]{6,18}$/ 十六进制值:/^#?([a-f0-9]{6}|[a-f0-9]{3})$/ 电子邮 ...
- springboot(十二)-分布式锁(redis)
什么是分布式锁? 要介绍分布式锁,首先要提到与分布式锁相对应的是线程锁.进程锁. 线程锁:主要用来给方法.代码块加锁.当某个方法或代码使用锁,在同一时刻仅有一个线程执行该方法或该代码段.线程锁只在同一 ...
- HttpClient 工具类
package com.sys.utils; import java.io.IOException; import java.net.URI; import java.util.ArrayList; ...
- Scrapyd API的安装
安装好了Scrapyd之后,我们可以直接请求它提供的API来获取当前主机的Scrapy任务运行状况.比如,某台主机的IP为192.168.1.1,则可以直接运行如下命令获取当前主机的所有Scrapy项 ...
- xilinx DMA IP核(一) —— loop测试 代码注释
本篇笔记中的代码来自:米联科技的教程“第三季第一篇的DMA_LOOP环路测试” 硬件的连接如下图所示: 图:DMA Loop Block Design 橘色的线就是DMA加FIFO组成的一个LOOP循 ...
- redux设计到源码 --- 美团点评技术团队(转)
https://tech.meituan.com/redux-design-code.html