threadlocal

ThreadLocal使用方法

别说谁变了你拦得住时间么 提交于 2020-01-07 12:00:39
ThreadLocal:用于实现线程内部的数据共享叫线程共享(对于同一个线程内部数据一致),即相同的一段代码 多个线程来执行 ,每个线程使用的数据只与当前线程有关。 实现原理:ThreadLocal相当于一个map 当前线程 存储当前的变量的时候 map.put(确定线程的唯一值(比如变量名称),变量),然后获取的时候直接拿过来就行 一般用法:定义一个全局变量ThreadLoacl t 将新建线程要使用的变量 存进去 比如 1.当存储的为基本变量或者包装对象时 关于多线程打印结果问题,详见( https://blog.csdn.net/qq_44868502/article/details/103869078 ) package com.yanghs.test.traditional; /** * @author yanghs * @Description: * @date 2018/3/31 16:24 */ public class ThreadLocalTest { /*定义一个全局变量 来存放线程需要的变量*/ public static ThreadLocal<Integer> ti = new ThreadLocal<Integer>(); public static void main(String[] args) { /*创建两个线程*/ for(int i=0;

ThreadLocal使用详解

放肆的年华 提交于 2020-01-07 09:46:55
The Thread-Specific Storage 线程保险箱 官方解释 This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID). 该类提供线程局部变量。这些变量与普通的对应变量不同,因为每个访问一个变量的线程(通过其get或set方法)都有自己独立初始化的变量副本。ThreadLocal实例通常是希望将状态与线程(例如,用户ID或事务ID)关联的类中的私有静态字段。 ThreadLocal的初始化设定值和set设置值 package com.dwz.concurrency.chapter33;

easypoi导入Excel最佳实践

你离开我真会死。 提交于 2020-01-07 09:40:45
前言 本文原文链接地址:http://nullpointer.pw/easypoi%E5%AF%BC%E5%85%A5Excel%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5.html 一直以来,使用EasyPOI做了不少导入导出的需求,但是每次做完都是临时去看官方文档现学现用,正巧最近朋友遇到这么个需求,用到了EasyPOI来完成导入,我也正好整理整理EasyPOI的导入用法。 本文原文链接地址:http://nullpointer.pw/easypoi%E5%AF%BC%E5%85%A5Excel%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5.html 需求是这样的:现在要在后台导入用户的简历,简历的格式是这样子的: 一个人有多个属性,某些属性如申请职位、薪资是单一属性,即只会有一个值;某些属性如工作经历、教育经历、获奖情况是一组属性,可能会有多组值。现在要将这批简历数据导入到库中。 零、文件准备: 示例Excel以及示例Excel2 加入 EasyPOI 的依赖 <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-web</artifactId> <version>3.2.0</version> </dependency> 一

Synchronized、Threadlocal、Volatile

孤人 提交于 2020-01-05 03:21:36
synchronized: synchronized叫做同步锁,操作起来方便,只需要在一个方法或把需要同步的代码块包装在它内部,那么这段代码就是同步的了,所有线程对这块区域的代码访问必须先持有锁才能进入,否则则拦截在外面等待正在持有锁的线程处理完毕再获取锁进入正因为它基于这种阻塞的策略,所以它的性能不太好,但是由于操作上的优势, 只需要简单的声明一下即可,而且被它声明的代码块也是具有操作的原子性。 threadlocal (本地单机) 用来提供线程内的局部变量,这样每个线程都自己管理自己的局部变量,别的线程操作的数据不会对我产生影响,互不影响 就是把变量分成很多个拷贝,每个线程拥有一个。这里没有所谓的最后的结果,每个线程单独操作自己的变量,和其他的变量没关系,互不干扰 ThreadLocalMap类的定义是在ThreadLocal类中,真正的引用却是在Thread类中。同时,ThreadLocalMap中用于存储数据的entry定义,它是一个Map,他的key是ThreadLocal实例对象。 1、JVM利用设置ThreadLocalMap的Key为弱引用,来避免内存泄露。 2、JVM利用调用remove、get、set方法的时候,回收弱引用 3、当ThreadLocal存储很多Key为null的Entry的时候,而不再去调用remove、get、set方法,那么将导致内存泄漏 4

并发编程之多线程线程安全(上)

拜拜、爱过 提交于 2020-01-04 06:14:09
1、为什么有线程安全问题? 当多个线程共享同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题。但是做读操作是不会发生数据冲突问题。 案例:现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。 代码: public class NewThread1 implements Runnable{ private int trainCount = 100; @Override public void run() { while (trainCount>0){ try { Thread.sleep(100); }catch (Exception e){ } save(); } } private void save() { if (trainCount > 0) { System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - trainCount + 1) + "张票"); trainCount--; } } public static void main(String[] args){ NewThread1 newThread1 = new NewThread1(); Thread thread1 = new Thread(newThread1,"①");

全局变量引起的并发问题【高并发、多线程】—— ThreadLocal

强颜欢笑 提交于 2020-01-03 05:37:23
文章目录 全局变量引起的并发问题【高并发、多线程】 背景 模拟重现demo(部分代码略) 代码问题分析 解决方案-ThreadLocal 模拟验证 全局变量引起的并发问题【高并发、多线程】 背景 最近采用RabbitMQ做核心系统 团车 缴费解耦功能,消费端应用采用了 SpringBoot2.1+Redis+RabbitMQ+jdbctemplate+Oaracle 架构。 此消费端应用以前 单车 缴费时未出现任何问题,从监听—>日志输出—>业务逻辑处理等一切正常。 线上业务高峰期时也没有任何问题。 但是团车缴费功能启用时,多个 200笔数据同时消费 时就出现了数据 篡改 情况。 问题不难,看了日志之后发现对并发处理的不够到位。 结合着之前redis高并发多线程总结,顺便对这里也进行记录,希望帮助大家总结经验 另外一篇文章链接: redis高并发导致读写变慢(redis多线程) 模拟重现demo(部分代码略) @Bean public class controllerA { private BillingMQServiceImpl billingMQServiceimpl ; public A ( ) { log . info ( "监听到billing消息队列消息:" ) ; billingMQServiceimpl . process ( new String ( body ,

13.ThreadLocal

放肆的年华 提交于 2019-12-30 23:36:26
ThreadLocal类型的变量为线程本地变量,大概的原理就是建立了一个Map,然后key是线程,value是指,通过get方法就能取到每个线程自己的变量副本 1. ThreadLocal使用 2. ThreadLocal源码分析 public class ThreadLocal<T> { // 设置属性 public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); // 找到当前线程里的map if (map != null) map.set(this, value); // 将 键值对 threadLocal的this 和 value 放入到当前线程的map中 else createMap(t, value); } // 获取属性 public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); // 获取map if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); // 通过 threadLocal的this 获取到value if (e != null) {

深度解析ThreadLocal,以及使用ThreadLocal存在的问题

微笑、不失礼 提交于 2019-12-29 13:10:52
ThreadLocal使用方式为在一个线程中创建一个ThreadLocal对象,使用threadLocal.set()赋值,在相同线程的另一个地方使用threadLocal.get()获取值,接下来,从源码角度分析一下ThreadLocal的实现方式以及存在的问题。 1:创建是直接new 一个对象创建出来,既然ThreadLocal与线程已经绑定(一个ThreadLocal在不同的线程之中可以存放不同的值),接下来看下ThreadLocal与线程是如何进行绑定的 public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } 以上是ThreadLocal的set方法,先获取到当前的线程,然后通过getMap(t)获取到当前线程的ThreadLocalMap,ThreadLocalMap是ThreadLocal的静态内部类,在getMap()方法中可以看到ThreadLocalMap其实是Thread的一个属性(每一个线程都有自己专属的ThreadLocalMap)。 ThreadLocalMap getMap(Thread t)

【面试】如果你这样回答“什么是线程安全”,面试官都会对你刮目相看

十年热恋 提交于 2019-12-29 03:07:29
有读者跟我说,喜欢看我的文章,说很容易读,我确实在易读性上花费的心思不亚于在内容上。因为我不喜欢一上来就堆很多东西,而且把简单的东西搞得复杂人人都会,但是把复杂的东西讲的简单,确实需要非常多的思考。 不是线程的安全 面试官问:“什么是线程安全”,如果你不能很好的回答,那就请往下看吧。 论语中有句话叫“学而优则仕”,相信很多人都觉得是“学习好了可以做官”。然而,这样理解却是错的。切记望文生义。 同理,“线程安全”也不是指线程的安全,而是指内存的安全。为什么如此说呢?这和操作系统有关。 目前主流操作系统都是多任务的,即多个进程同时运行。为了保证安全,每个进程只能访问分配给自己的内存空间,而不能访问别的进程的,这是由操作系统保障的。 在每个进程的内存空间中都会有一块特殊的公共区域,通常称为堆(内存)。进程内的所有线程都可以访问到该区域,这就是造成问题的潜在原因。 假设某个线程把数据处理到一半,觉得很累,就去休息了一会,回来准备接着处理,却发现数据已经被修改了,不是自己离开时的样子了。可能被其它线程修改了。 比如把你住的小区看作一个进程,小区里的道路/绿化等就属于公共区域。你拿1万块钱往地上一扔,就回家睡觉去了。睡醒后你打算去把它捡回来,发现钱已经不见了。可能被别人拿走了。 因为公共区域人来人往,你放的东西在没有看管措施时,一定是不安全的。内存中的情况亦然如此。 所以线程安全指的是

【面试】如果你这样回答“什么是线程安全”,面试官都会对你刮目相看

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-29 03:07:16
好文章来自: https://www.cnblogs.com/lixinjie/p/a-answer-about-thread-safety-in-a-interview.html#4279679 不是线程的安全 面试官问:“什么是线程安全”,如果你不能很好的回答,那就请往下看吧。 论语中有句话叫“学而优则仕”,相信很多人都觉得是“学习好了可以做官”。然而,这样理解却是错的。切记望文生义。 同理,“线程安全”也不是指线程的安全,而是指内存的安全。为什么如此说呢?这和操作系统有关。 目前主流操作系统都是多任务的,即多个进程同时运行。为了保证安全,每个进程只能访问分配给自己的内存空间,而不能访问别的进程的,这是由操作系统保障的。 在每个进程的内存空间中都会有一块特殊的公共区域,通常称为堆(内存)。进程内的所有线程都可以访问到该区域,这就是造成问题的潜在原因。 假设某个线程把数据处理到一半,觉得很累,就去休息了一会,回来准备接着处理,却发现数据已经被修改了,不是自己离开时的样子了。可能被其它线程修改了。 比如把你住的小区看作一个进程,小区里的道路/绿化等就属于公共区域。你拿1万块钱往地上一扔,就回家睡觉去了。睡醒后你打算去把它捡回来,发现钱已经不见了。可能被别人拿走了。 因为公共区域人来人往,你放的东西在没有看管措施时,一定是不安全的。内存中的情况亦然如此。 所以线程安全指的是