Java并发编程之threadLocal
目录
- 1、ThreadLocal介绍
- 2、ThreadLocal使用实例
- 3、ThreadLocal实现原理
1、ThreadLocal介绍 多个线程访问同一个共享变量时特别容易出现并发问题,特别是多线程需要对共享变量进行写入时。为了保证线程安全,一般使用者在访问共享变量的时候需要进行适当的同步,如图
![Java并发编程之threadLocal](https://img.it610.com/image/info11/71e2dd2853ab4c6483480e9b0842893d.jpg)
文章图片
同步的一般措施是加锁,这就需要使用者对锁有一定的了解,这显然加重了使用者的负担,那么有没有一种方法可以做到,当创建一个变量后,每个线程对其进行访问的时候访问的是自己线程的变量呢?其实
ThreadLocal
就可以做到。ThreadLocal
是JDK
包提供的,它提供了线程本地变量,也就是说如果创建了一个ThreadLocal
变量,那么访问这个变量的每一个线程都会有这个变量的一个本地副本。当多线程操作这个变量的时候,实际操作的就是自己本地内存的里面的里面的变量,从而避免了线程安全问题。创建一个ThreadLocal
变量后,每一个线程都会复制一个变量到自己的本地内存。![Java并发编程之threadLocal](https://img.it610.com/image/info11/d1e0c5c3276849f8a7998bed90db5cf1.jpg)
文章图片
2、ThreadLocal使用实例
package com.heiye.learn1; public class ThreadLocalTest {//print方法static void print(String threadName) {//打印当前线程本地内存中LocalVariable变量的值System.out.println(threadName + ":" + localVariable.get()); //清除当前线程本地内存中的localVariable变量值//localVariable.remove(); }//创建ThreadLocal变量static ThreadLocal localVariable = new ThreadLocal<>(); public static void main(String[] args) {//创建线程threadOneThread threadOne = new Thread(new Runnable() {@Overridepublic void run() {//设置线程one变量localVariable值localVariable.set("threadOne local Variable"); //调用打印函数print("threadOne"); //打印本地变量值System.out.println("threadOne remove after" + ":" + localVariable.get()); }}); //创建线程threadTwoThread threadTwo = new Thread(new Runnable() {@Overridepublic void run() {//设置线程two变量localVariable值localVariable.set("threadTwo local Variable"); //调用打印函数print("threadTwo"); //打印本地变量值System.out.println("threadTwo remove after" + ":" + localVariable.get()); }}); threadOne.start(); threadTwo.start(); }}
![Java并发编程之threadLocal](https://img.it610.com/image/info11/31e7394d0d1c4b5880a429fbfcd06c0c.jpg)
文章图片
线程
one
首先通过set()
方法为threadLocal
变量设置了一个值,这其实设置的就是线程one本地内存中对于threadLocal变量的一个副本。这个副本是线程two访问不了的。如果清除当前线程本地内存中的
localVariable
变量值,也就是执行localVariable.remove()
;
则:![Java并发编程之threadLocal](https://img.it610.com/image/info11/ac2940da987a42eead6192cefac90df5.jpg)
文章图片
3、ThreadLocal实现原理 首先查看一下
ThreadLocal
类图结构![Java并发编程之threadLocal](https://img.it610.com/image/info11/d5a0c7fcc120463c8701bb7f38a7ea99.jpg)
文章图片
由该图可知,
Thread
类有一个ThreadLocals
和inheritableThreadLocals
,它们都是ThreadLocalMap
类型的变量,而ThreadLocalMap
是一个定制化的HashMap
。在默认的情况下,每个线程中的两个变量都为null,只有当第一个线程调用ThreadLocal
的set或者get方法时才会创建它们,其实每个线程得到本地变量不是存放在ThreadLocal
实例里面,而是存放在具体的线程内存空间里。ThreadLocal
就是一个工具壳,它通过set方法把value值存放在调用线程的threadlocals
里面并存放起来,当调用线程调用它的get()方法的时候,再从当前线程的threadLocals
变量里面将其拿出来使用。分析
set
,get
,remove
逻辑//set public void set(T value) {//获取当前线程Thread t = Thread.currentThread(); //将当前线程作为key,到ThreadLocalMap取查找对应的线程变量ThreadLocalMap map = getMap(t); //如果找到,则设置if (map != null)map.set(this, value); else //第一次调用就创建当前线程所在的hashmapcreateMap(t, value); } //get public T get() {Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) {ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) {@SuppressWarnings("unchecked")T result = (T)e.value; return result; }}return setInitialValue(); } //remove public void remove() {ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null)m.remove(this); }
在每一个线程内都有一个名为
threadLocals
的成员变量,该变量的类型为HashMap
,其中的key为我们定义的threadLocal
变量的this引用,value
为我们使用set方法设置的值。每个线程的本地变量存放在自己的内存变量ThreadLocals
中,如果当前线程一直不消亡,那么这些本地变量会一直存在,所有可能造成内存溢出。【Java并发编程之threadLocal】到此这篇关于Java并发编程 threadLocal 的文章就介绍到这了,更多相关threadLocal 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 事件代理
- Java|Java OpenCV图像处理之SIFT角点检测详解
- java中如何实现重建二叉树
- 数组常用方法一
- 【Hadoop踩雷】Mac下安装Hadoop3以及Java版本问题
- python青少年编程比赛_第十一届蓝桥杯大赛青少年创意编程组比赛细则
- Java|Java基础——数组
- RxJava|RxJava 在Android项目中的使用(一)
- java之static、static|java之static、static final、final的区别与应用