threadlocal

java并发之ThreadLocal

不想你离开。 提交于 2020-03-04 07:47:39
ThreadLocal的思考: 描述: 方法1:传入秒数,new一个SimpleDataFormat对象,返回时间字符串 方法2:生成两个线程,每个线程都去调用方法1来打印不同秒数的时间 结果:运行正常 进一步思考:要是1000个线程呢?用线程池,生成10线程 进一步思考:在方法1中,每次调用都会new一个SimpleDataFormat对象,浪费开销 解决方法:将SimpleDataFormat作为全局变量 运行结果:线程出现并发冲突问题,会有相同时间结果。原因是多个线程共享了SimpleDataFormat对象。 解决方法:加锁,用synchronized 进一步思考:虽然现在sm只生成了一次,但多个线程在加锁部分部分代码是串行执行的,没有并发,效率低 优化:在线程池有10线程,让每个线程都有自个的sm对象,这样,10线程之间就可以并发执行,sm也没有创建很多个 实现方式: 用ThreadLocal给当前线程赋予独立的变量 另一个场景,服务器接收请求,有用户信息,不同方法使用同一个用户信息。 分析:不同请求对应不同线程,每个线程都用ThreadLocal来保存用户信息,则不会发生冲突,且用户信息也不用作为方法参数传来传去 源码分析: 在Thread对象中,有一个map,key为ThreadLocal对象,value为用户定义的值,这样,每个线程都有独立的变量存储map

Java面试全解析(22)ThreadLocal 有什么用

浪尽此生 提交于 2020-03-03 15:24:09
什么是 ThreadLocal? ThreadLocal 诞生于 JDK 1.2,用于解决多线程间的数据隔离问题。也就是说 ThreadLocal 会为每一个线程创建一个单独的变量副本。 ThreadLocal 有什么用? ThreadLocal 最典型的使用场景有两个: ThreadLocal 可以用来管理 Session,因为每个人的信息都是不一样的,所以就很适合用 ThreadLocal 来管理; 数据库连接,为每一个线程分配一个独立的资源,也适合用 ThreadLocal 来实现。 其中,ThreadLocal 也被用在很多大型开源框架中,比如 Spring 的事务管理器,还有 Hibernate 的 Session 管理等,既然 ThreadLocal 用途如此广泛,那接下来就让我们共同看看 ThreadLocal 要怎么用?ThreadLocal 使用中要注意什么?以及 ThreadLocal 的存储原理等,一起来看吧。 ThreadLocal 基础使用 ThreadLocal 常用方法有 set(T)、get()、remove() 等,具体使用请参考以下代码。 ThreadLocal threadLocal = new ThreadLocal(); // 存值 threadLocal.set(Arrays.asList( "老王" , "Java 面试题" )); /

ThreadLocal来源推断

你离开我真会死。 提交于 2020-03-01 21:08:36
问题 同一个线程内多个方法间如何共享变量? 方法a 类成员变量本来就是各个线程各有一份,线程内共享的。 class MyThread extends Thread { String myvar ; public void run ( ) { //do something } public void method1 ( ) { myvar = "hi" ; System . out . println ( myvar ) ; } public void method1 ( ) { System . out . println ( myvar ) ; } } 问题升级1 若需要线程内共享的变量数量多,类型各不相同呢? 类方法a 把每个要共享的变量都声明为成员 方法b 思路:声明一个啥类型都可以兼容的Map,把所有变量都丢进去 class MyThread extends Thread { String key1 = "KEY1" ; String key2 = "KEY2" ; Map < String , Object > myMap = new HashMap < > ( ) ; public void run ( ) { //do something } public void method1 ( ) { myMap . put ( key1 , "hi" ) ; }

Java并发编程:深入剖析ThreadLocal

我怕爱的太早我们不能终老 提交于 2020-03-01 10:34:29
个人博客导航页(点击 右侧 链接 即可打开个人博客): 大牛带你入门技术栈 想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadLocal的使用方法和实现原理。首先,本文先谈一下对ThreadLocal的理解,然后根据ThreadLocal类的源码分析了其实现原理和使用需要注意的地方,最后给出了两个应用场景。   以下是本文目录大纲:   一.对ThreadLocal的理解   二.深入解析ThreadLocal类   三.ThreadLocal的应用场景   若有不正之处请多多谅解,并欢迎批评指正。   请尊重作者劳动成果,转载请标明原文链接:    http://www.cnblogs.com/dolphin0520/p/3920407.html 一.对ThreadLocal的理解 ThreadLocal,很多地方叫做线程本地变量,也有些地方叫做线程本地存储,其实意思差不多。可能很多朋友都知道ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。   这句话从字面上看起来很容易理解,但是真正理解并不是那么容易。   我们还是先来看一个例子: class ConnectionManager { private static Connection connect = null; public static

ThreadLocal理解和应用

谁说我不能喝 提交于 2020-03-01 07:11:13
本篇博客将为大家介绍一下ThreadLocal。从用途、使用方法、原理、及常见问题四个方面来介绍。 1.ThreadLocal用途 ThreadLocal用途可以理解成一个“储物间”,这个 “储物间”当中拥有大量的“储物柜 ”,每个“ 储物柜 ”实际上就是 每个线程 ,当中存放的是Thread线程中参数,针对于ThreadLocal的set方法 其实就是将参数放入到当前线程对应的“储物柜”当中(根据Thread.currentThread()进行区分线程) ,同样get()和remove()方法也是一样。 2.ThreadLocal使用方法 下面我们编写一个程序,每个线程保存一个自己的ID数据,然后多次调用进行修改ID数据并将其打印。 public class ThreadLocalIds { private static final ThreadLocal<AtomicInteger> THREAD_LOCAL = new ThreadLocal<AtomicInteger>() { protected AtomicInteger initialValue() { return new AtomicInteger(0);// threadlocal中初始化值,每个线程的ID都从0开始增加 }; }; public static int getIntValue() {

java ThreadLocal

与世无争的帅哥 提交于 2020-03-01 01:13:29
JDKAPI 解释: 该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其get或set方法)的每个线程都有自己的局部变量,它独立于 初始化 变量的副本。ThreadLocal实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。 资料查找总结: ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。 个人认为ThreadLocal 就是一种Map key-value 的实现思路。当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本 。将每个线程作为key ,线程操作的数据作为value。每个线程可以独立修改自己的value ,而不影响其他线程对应的value。 ThreadLocal方法详细信息 : initialValue protected T initialValue()返回此线程局部变量的当前线程的“初始值”。线程第一次使用 get() 方法访问变量时将调用此方法,但如果线程之前调用了 set(T) 方法,则不会对该线程再调用 initialValue 方法。通常,此方法对每个线程最多调用一次,但如果在调用 get() 后又调用了

Java架构直通车——ThreadLocal实现RabbitMQ消息的批量发送

做~自己de王妃 提交于 2020-02-29 12:25:15
文章目录 引入 什么是ThreadLocal 使用ThreadLocal 引入 之前,我们完成了 单个消息的发送,以及单个消息发送的多线程池化 。 这里,我们继续完成批量发送消息的封装。 因为rabbitMq本身是不支持批量发消息的,所以我们可以直接使用上文所创建的连接池来发送。 最简单的代码是这样的: # ProducerClient . class @Override public void send ( List < Message > messages ) throws MessageRuntimeException { messages . forEach ( message - > { message . setMessageType ( MessageType . RAPID ) ; } ) ; rabbitBroker . sendMessages ( messages ) ; } # RabbitBrokerImpl . class @Override public void sendMessages ( List < Message > messages ) { messages . forEach ( message - > { sendKernel ( message ) ; } ) ; } 这里使用ThreadLocal

刨根问底-ThreadLocal线程安全

孤人 提交于 2020-02-29 09:17:30
1、线程安全,值得是在多线程环境先,一个类在执行某个方法时,对类的内部实例变量的访问时安全的。因此,对于下面列出来的2类变量,不存在任何线程安全的说法: (1)方法签名中的任何参数变量 (2)处于方法内部的局部变量 线程安全针对于类内部的全局变量 2、java.lang.ThreadLocal类是jdk提供一种解决多线程并发问题方案。 ThreadLocal类在维护变量时,实际使用了当前线程Thread中的一个叫做ThreadLocalMap的独立副本,每个线程可以独立修改属于自己的副本而不会相互影响,从而隔离了线程和线程,避免了线程访问实例变量发生冲突的问题。 TreadLocal本身并不是一个线程,而是通过操作当前线程中的一个内部变量来达到与其他线程隔离的目的。之所以叫TdreadLocal,表示了其操作的对象时线程的一个本地变量。 现在看Thread代码: public class Thread implements Runnable { ThreadLocal.ThreadLocalMap threadLocals = null; } ThreadLocalMap跟随者当前的线程而存在。不用的线程Thread,拥有不同的ThreadLocalMap的本地实例变量,这就是副本的含义。 ThreadLocal是如何操作ThreadLocalMAP的 : public class

深入研究java.lang.ThreadLocal类

我的梦境 提交于 2020-02-29 08:45:26
一、概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是Java中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。 从线程的角度看,每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非存在对这些副本的其他引用)。 通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。 ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。 概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问

项目问题总结一、全局变量引起的并发问题

空扰寡人 提交于 2020-02-28 23:26:32
最近刚完成了一个短彩信群发平台的开发工作,系统采用springmvc+hibernate+jdbctemplate+mysql架构。其中遇见许多问题,闲暇之余记录下来以避免在后续项目中再犯同样的错误。 先看下面小段代码,一个controller,一个service。 controller.java代码: ........ @Autowired private XXXService xxxService; ........ @RequestMapping("/doXXX.do") public void doXXX(){ ..... xxxService.saveXXX(String content,....); ..... } XXXService.java代码: private String content; ...... private void init(){//清空请求参数 content = null; ...... } public boolean saveXXX(String content, ......){ this.init(content, ...); this.content = content; //业务逻辑处理 } 以上这段代码在访问量不构成并发时不会出现什么问题。 但当一个请求还未完成,另一个请求已经开始执行的情况下就会出现问题(并发):