threadlocal

Java 中熟悉而又陌生的 ThreadLocal

≡放荡痞女 提交于 2019-12-10 20:43:39
ThreadLocal 是什么? 要学习一个新东西至少要知道它是什么?这点应该是确定的。那么 ThreadLocal 到底是什么呢?其实Thread(线程)、Local(本地)这两个单词都不算太难,在平时也是屡见不鲜,ThreadLocal 很容易让人望文生义,想当然地认为是一个“本地线程”。其实 ThreadLocal 并不是一个 Thread,而是 Thread 的局部变量。那么它的作用到底是什么?先来看看JDK(13)文档的解释: 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).

InheritableThreadLocal使用详解

守給你的承諾、 提交于 2019-12-10 17:56:26
引子 public class InheritableThreadLocalDemo { private static ThreadLocal<String> threadLocal = new ThreadLocal<>(); public static void main(String[] args) { threadLocal.set("mainThread"); System.out.println("value:"+threadLocal.get()); Thread thread = new Thread(new Runnable() { @Override public void run() { String value = threadLocal.get(); System.out.println("value:"+value); } }); thread.start(); } } 上面代码中在主线程中设置了一个ThreadLocal变量,并将其值设置为 mainThread 。然后有在主线程中开启了一个子线程 thread ,并试图获取在主线程中set的ThreadLocal变量的值。但是结果如下: value:mainThread value:null 通过前面的文章介绍,对于上面的结果我们也就非常容易理解了。每个线程都会有一个自己的ThreadLocalMap

ThreadLocal

ε祈祈猫儿з 提交于 2019-12-10 13:35:40
一、概述 ThreadLocal是什么? 其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,惹事ThreadLocalvariable(线程局部变量)。线程局部变量(ThreadLocal)其实功能非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是java中一种较为特殊的线程绑定机制,使每一个线程都可以独立的改变自己的副本,而不会和其他线程的副本冲突。 从线程角度看,每个线程都保持一个对其线程局部变量的隐式引用,只要线程是活动的并且ThreadLocal实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非存在对这些副本的其他引用)。 通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发问题提供了一种隔离机制。 概况起来说,对于多线程资源共享的问题,同步机制采用了"以时间换空间"的方式,而ThreadLocal采用了"以空间换时间"的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。 二、API说明 ThreadLocal():创建一个线程本地变量。 protected T initialValue():返回此线程局部变量的当前线程的初始值

ThreadLocal与Synchronized

穿精又带淫゛_ 提交于 2019-12-10 00:04:49
ThreadLocal使用场合主要解决多线程中数据数据因并发产生不一致问题。ThreadLocal为每个线程的中并发访问的数据提供一个副本,通过访问副本来运行业务,这样的结果是耗费了内存,单大大减少了线程同步所带来性能消耗,也减少了线程并发控制的复杂度。 ThreadLocal和Synchonized都用于解决多线程并发访问。但是ThreadLocal与synchronized有本质的区 别。synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本, 使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。而Synchronized却正好相反,它用于在多个线程间通 信时能够获得数据共享。 Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。 ThreadLocal类详解请查看 http://www.cnblogs.com/dolphin0520/p/3920407.html ThreadLocal类实例请查看 http://blog.csdn.net/yemaozi2009/article/details/39212167 来源: oschina 链接: https://my.oschina.net/u/2000675/blog

ThreadLocal 源码解读

大兔子大兔子 提交于 2019-12-08 22:36:31
一、引入 public class Thread implements Runnable { /* 前面略 */ /* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ ThreadLocal.ThreadLocalMap threadLocals = null; /* 后面略 */ } 首先我们看到的是 Thread 中有一个属性 threadLocals,它的类型是 ThreadLocalMap,封装类型是 default(表示它只能在包内可见),jdk 是这么介绍它的:与此线程有关的 ThreadLocal 值,该映射由 ThreadLocal 类维护。 啥意思呢?那就来看看 ThreadLocalMap 是啥玩意! public class ThreadLocal<T> { /* 前面略 */ static class ThreadLocalMap { /** * The entries in this hash map extend WeakReference, using * its main ref field as the key (which is always a * ThreadLocal object).

ThreadLocal 那点事儿(续集)

£可爱£侵袭症+ 提交于 2019-12-07 21:01:29
本篇是《 ThreadLocal 那点事儿 》的续集,如果您没看上一篇,就就有点亏了。如果您错过了这一篇,那亏得就更大了。 还是保持我一贯的 Style,用一个 Demo 来说话吧。用户提出一个需求:当修改产品价格的时候,需要记录操作日志,什么时候做了什么事情。 想必这个案例,只要是做过应用系统的小伙伴们,都应该遇到过吧?无外乎数据库里就两张表:product 与 log,用两条 SQL 语句应该可以解决问题: update product set price = ? where id = ? insert into log (created, description) values (?, ?) But!要确保这两条 SQL 语句必须在同一个事务里进行提交,否则有可能 update 提交了,但 insert 却没有提交。如果这样的事情真的发生了,我们肯定会被用户指着鼻子狂骂:“为什么产品价格改了,却看不到什么时候改的呢?”。 聪明的我在接到这个需求以后,是这样做的: 首先,我写一个 DBUtil 的工具类,封装了数据库的常用操作: public class DBUtil { // 数据库配置 private static final String driver = "com.mysql.jdbc.Driver"; private static final String url =

ThreadLocal 那点事儿

会有一股神秘感。 提交于 2019-12-07 11:39:53
ThreadLocal,直译为“线程本地”或“本地线程”,如果你真的这么认为,那就错了!其实,它就是一个容器,用于存放线程的局部变量,我认为应该叫做 ThreadLocalVariable(线程局部变量)才对,真不理解为什么当初 Sun 公司的工程师这样命名。 早在 JDK 1.2 的时代,java.lang.ThreadLocal 就诞生了,它是为了解决多线程并发问题而设计的,只不过设计得有些难用,所以至今没有得到广泛使用。其实它还是挺有用的,不相信的话,我们一起来看看这个例子吧。 一个序列号生成器的程序,可能同时会有多个线程并发访问它,要保证每个线程得到的序列号都是自增的,而不能相互干扰。 先定义一个接口: public interface Sequence { int getNumber(); } 每次调用 getNumber() 方法可获取一个序列号,下次再调用时,序列号会自增。 再做一个线程类: public class ClientThread extends Thread { private Sequence sequence; public ClientThread(Sequence sequence) { this.sequence = sequence; } @Override public void run() { for (int i = 0; i < 3;

Java 线程之 ThreadLocal

橙三吉。 提交于 2019-12-07 08:35:26
ThreadLocal : 与synchronize作用相反,synchronize为的是实现并发,将资源加锁,保证某时刻只有一个线程能够访问该线程。而ThreadLocal保证每个线程访问都是新new的对象。ThreadLocal和Synchronize使用场景完全不同,不能混用。 这样消耗内存,但是却减少了并发带来性能消耗,其实就是空间换时间的概念。 最常见的ThreadLocal使用场景为 用来解决 数据库连接、Session管理等。 ####参考: Java并发编程:深入剖析ThreadLocal 来源: oschina 链接: https://my.oschina.net/u/2300623/blog/701012

Netty精粹之设计更快的ThreadLocal

老子叫甜甜 提交于 2019-12-06 23:34:00
Netty是一款优秀的开源的NIO框架,其异步的、基于IO事件驱动的设计以及简易使用的API使得用户快速构建基于NIO的高性能高可靠性的网络服务器成为可能。Netty除了使用Reactor设计模式加上精心设计的线程模型之外,对于线程创建的具体细节也进行了重新设计,由于Netty的应用场景主要面向高并发高负载的场景下,这也是Netty能够大显身手的场景,因此,Netty不放过任何优化性能的机会。这篇文章主要介绍Netty线程模型基础部分——线程创建相关以及FastThreadLocal实现方面的一些细节以及和传统的ThreadLocal之间的性能比较数据。 传统的ThreadLocal ThreadLocal最常用的两个接口是set和get,前者是用于往ThreadLocal设置内容,后者是从ThreadLocal中取内容。最常见的应用场景为在线程上下文之间传递信息,使得用户不受复杂代码逻辑的影响。我们来看看他们的实现原理: public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); t.threadLocals; 我们使用set的时候实际上是获取Thread对象的threadLocals属性,把当前ThreadLocal当做参数然后调用其set

String引发的提问,我差点跪了

做~自己de王妃 提交于 2019-12-06 21:13:42
面试官:下面代码执行结果是什么?String t0 = "helloworld";String t1 = new String("helloworld");System.out.println(t0==t1); 小白:(心里嘀咕:不会这么简单吧)false 面试官:详细解释一下为什么? 小白:在Java虚拟机栈中创建一个String类型变量t0,然后会优先在方法区的运行时常量池中查找是否已经存在相同的字符串,倘若已经存在,栈中t0变量直接指向该字符串;倘若不存在,则在常量池中创建一个"helloworld"字符串,再将栈中t0变量指向该字符串。通过new关键字创建字符串对象,首先当前类被加载后,会在方法区的运行时常量池中查找是否已经存在"helloworld"字符串,如果不存在,则将编译期生成的"helloworld"存到运行时常量池中,如果已存在不存放,在堆中生成一个String类型的对象,栈中t1变量指向该对象。因为t0和t1指向的对象不同,当使用==做比较时,比较的是对象的引用(可能是指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其它与此对象相关的位置),自然返回的是false。 面试官:那下面代码的运行结果又是什么?String t0 = new String("hello") + new String("world");t0.intern();String