IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【java并发编程】ThreadLocal线程本地类 -> 正文阅读

[Java知识库]【java并发编程】ThreadLocal线程本地类

?一、简介

ThreadLocal类是作为线程内部的局部变量而提供的。让这些变量在多线程环境下访问(get/set)时能保证各个线程里的变量相对独立于其他线程内的变量。

通过ThreadLocal创建的变量只能被当前线程访问,对其他线程不可见,故别的线程无法访问和修改,也就是说:对线程公有化变成对线程私有化。事实上每个线程中都有一个ThreadLocal变量副本。

相比于锁的性能:

java在使用锁的使用中会导致运行效率降低,ThreadLocal的使用彻底避免对共享资源的竞争,同时又可以不影响效率。ThreadLocal采?了“以空间换时间”的?式,为每?个线程都提供?份变量的副本,从?实现同时访问?互不影响,但因为每个线程都维护着?份副本,对内存空间的占?会增加。

二、ThreadLocal原理

ThreadLocalMap是定义在ThreadLocal类中的一个静态内部类。而它的结构和HashMap结构极其相似。有一个Entry[]数组存放数据。而这个Entry类是继承自WeakReference类的子类,这一点和HashMap有所不同。

??

get方法

get()方法就是从Thread中取出来ThreadLocalMap,然后通过ThreadLocal对象作为Key取出值;remove()方法则是取出ThreadLocalMap将ThreadLocal对应的数据移除。

set方法

当调?set?法时,将数据写?threadLocals这个Map对象中,这个Map的key为ThreadLocal当前对象,value就是我们存?的值。?threadLocals本?能保存多个ThreadLocal对象,相当于?个ThreadLocal集合。

解决hash冲突使用的是“开放寻址法”,区别于hashmap的链表法

缺点

内存泄漏问题

ThreadLocalMap中的Entry的Key是一个弱引用,因此如果在使用后不调用remove方法清除掉会导致对应的value内存泄漏。所以在使用完以后一定要记得调用remove方法清除数据。

三、ThreadLocal使用

public class Main {
    //1、定义一个private static的ThreadLocal对象。
    private static ThreadLocal<String> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) {
        //2、每个线程可以将当前线程需要存放在局部变量中,并且可以从中获取。
        threadLocal.set("");
        String s = threadLocal.get();

        //3、最后在使用完之后,需要将ThreadLocal中的值移除。
        threadLocal.remove();
    }
}

使用场景

主要是用来做线程间数据隔离。

例如:SimpleDateFormat这个工具类,它不是线程安全的,可以通过ThreadLocal在每个线程中放一份,保证线程安全。

四、FastThreadLocal类

FastThreadLocal是netty包的,具体是io.netty.util.concurrent包

1、FastThreadLocal由来

netty为什么要在再造一个FastThreadLocal类呢

因为ThreadLocal效率不高,具体为:

  • 查找当前Thread绑定的变量, 是通过在Map中根据ThreadLocal的hash去查找的,不如数组下标访问快。

  • 使用开放寻址法解决hash冲突时,效率非常低。也就是说当hash的index被占用后,会往后看是否有位置可能存放,如此往复,直到有空位为止.

  • Map扩容涉及到重新计算部分index, 最糟的情况还要挪动元素的位置

  • 当线程执行完, 最好清掉所绑定的threadlocal变量, 不然会内存泄漏. 现实中, 往往会忘记清理.

FastThreadLocal(下文简称ftl)直接使用数组避免了hash冲突的发生。

具体做法是:每一个FastThreadLocal实例创建时,分配一个下标index;分配index使用AtomicInteger实现,每个FastThreadLocal都能获取到一个不重复的下标。当调用ftl.get()方法获取值时,直接从数组获取返回,如return array[index],如下图:

对应ThreadLocal类

在原生的ThreadLocal中有三个角色,Thread,ThreadLocal和ThreadLocalMap。分别对应了Netty的FastThreadLocalThread,FastThreadLocal和InternalThreadLocalMap。

2、如何使用

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
</dependency>

        //1、Netty提供的DefaultThreadFactory 工厂类,创建的线程默认就是 FastThreadLocalThread 类型
        DefaultThreadFactory defaultThreadFactory = new DefaultThreadFactory(FastThreadLocalTest.class);

        //2、创建FastThreadLocal
        FastThreadLocal<String> fastThreadLocal = new FastThreadLocal<>();

        //3、工厂生产线程
        Thread thread = defaultThreadFactory.newThread(() -> {
            //4、设置变量
            fastThreadLocal.set("");
            //5、获取变量
            fastThreadLocal.get();
        });
        //6、启动线程
        thread.start();

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-06-08 18:52:54  更:2022-06-08 18:56:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:24:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码