threadlocal

ThreadLocal源码解析

◇◆丶佛笑我妖孽 提交于 2020-01-18 05:30:27
多线程并发访问临界资源,破坏原子操作,会导致线程安全问题。将公共变量与ThreadLocal进行绑定,线程使用该公共变量时拿到的是在该线程中的副本变量,即将线程中的数据进行了隔离,多个线程能使用该变量但互不影响。 变量值的存放路径为:Thread->ThreadLocalMap->Entry->value,ThreadLocal作为Entry的key,通过key可以拿到value。 ThreadLocalMap的数据结构示意图: 1. 成员变量 内部类ThreadLocalMap 中的Entry[] table 数组(数据结构),table的长度必须是2的n次方,size表示map中entry的个数,threshold表示扩容阈值。阈值通常为2/3*length。 ThreadLocalMap中内部类Entry的value表示线程存储的副本变量值。Entry继承WeakReference,Entry的key是ThreadLocal,是弱引用,在垃圾回收时被回收。 2. 构造方法 无参构造 3. 查找元素 public T get() { //获取当前执行线程 Thread t = Thread.currentThread(); //获取当前线程的成员变量threadLocals ThreadLocalMap map = getMap(t); if (map != null) { /

ThreadLocal三种使用场景

ε祈祈猫儿з 提交于 2020-01-18 02:08:43
关于ThreadLocal JDK1.2的版本中就提供java.lang.ThreadLocal类,每一个ThreadLocal能够放一个线程级别的变量, 它本身能够被多个线程共享使用,并且又能够达到线程安全的目的,且绝对线程安全。 ThreadLocal包含了四个方法: void set(Object value) -- 设置当前线程的线程局部变量的值。 public Object get() -- 该方法返回当前线程所对应的线程局部变量。 public void remove() -- 将当前线程局部变量的值删除,其目的是为了减少内存使用,加快内存回收。 protected Object initialValue() -- 返回该线程局部变量的初始值,该方法是一个protected的方法,目的是为了让子类覆盖而设计的。 正确理解 ThreadLocal变量,它的基本原理是,同一个 ThreadLocal 所包含的对象(对ThreadLocal< StringBuilder >而言即为 StringBuilder 类型变量),在不同的 Thread 中有不同的副本(实际上是不同的实例): 因为每个 Thread 内有自己的实例副本,且该副本只能由当前 Thread 使用; 既然其它 Thread 不可访问,那就不存在多线程间共享的问题。 有兴趣的可以去看官方文档描述的。

ThreadLocal原理分析

谁都会走 提交于 2020-01-16 09:58:17
ThreadLocal简介 ThreadLocal线程本地变量的副本,对一个线程内的变量的修改不影响其它线程的变量。即在多线程环境下,可以保证各个线程之间的变量互相隔离、相互独立。 ①ThreadLocal实例通常在类中被定义为private static ②ThreadLocal在线程的生命周期内起作用 ③空间换时间的设计思想 ThreadLocal用法 首先了解下ThreadLocal的基本用法 private static ThreadLocal<Map<String, String>> threadLocal = new MyThreadLocal(); private static class MyThreadLocal extends ThreadLocal<Map<String, String>>{ @Override protected Map<String, String> initialValue() { Map map = new HashMap<String, String>(); map.put("andy","18"); return map; } } public static void main(String[] args) { Map<String, String> result = threadLocal.get(); System.out

ThreadLocal源码分析

空扰寡人 提交于 2020-01-16 07:28:18
目录 ThreadLocal源码分析 简单分析 什么是ThreadLocal 大致实现思路 使用场景 源码分析 ThreadLocalMap ThreadLocal 参考博客 ThreadLocal源码分析 简单分析 什么是ThreadLocal ThreadLocal顾名思义可以理解为线程本地变量。也就是说如果定义了一个ThreadLocal,每个线程往这个ThreadLocal中读写是线程隔离(也就是每个线程读写都是自己的一份独立对象,与其他线程是无关的,当然前提是不同线程set的不是同一个对象的引用),互相之间不会影响的。它提供了一种将可变数据通过每个线程有自己的独立副本从而实现线程封闭的机制。 大致实现思路 Thread类有一个类型为ThreadLocal.ThreadLocalMap的实例变量threadLocals,也就是说每个线程有一个自己的ThreadLocalMap。ThreadLocalMap有自己的独立实现,可以简单地将它的key视作为ThreadLocal,value为代码中放入的值(实际上key并不是ThreadLocal本身,而是他的一个人弱引用)。每个线程在往某个ThreadLocal里赛值得时候,都会往自己的ThreadLocalMap里存,读也是以某个ThreadLocal作为引用,在自己的map里找对应的key,从而实现了线程隔离。 使用场景 1

ThreadLocal源码

£可爱£侵袭症+ 提交于 2020-01-15 21:23:09
public class ThreadId { // Atomic integer containing the next thread ID to be assigned private static final AtomicInteger nextId = new AtomicInteger(0); // Thread local variable containing each thread's ID private static final ThreadLocal<Integer> threadId = new ThreadLocal<Integer>() { @Override protected Integer initialValue() { return nextId.getAndIncrement(); } }; // Returns the current thread's unique ID, assigning it if necessary public static int get() { return threadId.get(); } } public class ThreadLocal { private final int threadLocalHashCode = nextHashCode(); private static

ThreadLocal = 本地线程?

a 夏天 提交于 2020-01-15 00:33:03
一、定义 ThreadLocal 是 JDK 包提供的,从名字来看, ThreadLocal 意思就是本地线程的意思。 1.1 是什么? 要想知道他是个啥,我们看看 ThreadLocal 的源码(基于 JDK 1.8 )中对这个类的介绍: This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its {@code get} or {@code set} method) has its own, independently initialized copy of the variable. {@code 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). 大致能够总结出: TreadLocal 可以给我们提供一个线程内的局部变量,而且这个变量与一般的变量还不同,它是每个线程独有的,与其他线程互不干扰的;

java的并发和多线程

99封情书 提交于 2020-01-13 03:34:27
本文主要讲解Java并发相关的内容,包括锁、信号量、堵塞队列、线程池等主要内容。 并发的优点和缺点 在讲述怎么利用多线程的情况下,我们先看一下采用多线程并发的优缺点。 优点 提高资源利用率 如读取一个目录下的所有文件,如果采用单线程模型,则从磁盘读取文件的时候,大部分 CPU 用于等待磁盘去读取数据。如果是采用多线程并发执行,则 CPU 可以在等待 IO 的时候去做其他的事情,以提高 CPU 的使用率,减少资源的浪费。 程序响应速度好 单线程模型下,假设一个 http 请求需要占用大量的时间来处理,则其他的请求无法发送请求给服务端。而多线程模式下,监听线程把请求传递给工作者线程,然后立刻返回去监听,可以去接收新的请求,而工作者线程则能够处理这个请求并发送一个回复给客户端。明显响应速度比单线程模型要好得多。 缺点 程序设计复杂度 多线程情况下,需要考虑线程间的通信、共享资源的访问,相对而言要比单线程程序负责一些。 上下文切换开销大 当 CPU 从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行。这种切换称为“上下文切换”。 CPU 会在一个上下文中执行一个线程,然后切换到另外一个上下文中执行另外一个线程。尤其是当线程数量较多时,这种开销很明显。 资源消耗

第四章-锁的优化及注意事项

泄露秘密 提交于 2020-01-12 20:14:56
4.1 有助于提高锁性能的几点建议 162 4.1.1 减少锁持有时间 162 系统持有锁时间越长锁竞争程度就越激烈,只对需要同步的代码块加锁,可以减小锁持有时间进而提高锁性能。 减少锁的持有时间有助于降低锁冲突的可能性,进而提高锁的并发能力。 4.1.2 减小锁粒度 163 减小锁粒度就是指缩小锁定对象的范围,从而减小锁冲突的可能性,进而提高并发能力。 例如:如ConcurrentHashMap中并不是对整个HashMap进行加锁,而是对其分段,每段分别加锁。(JDK1.8已经取消)使用这个方法的一个缺点是:当系统需要取得全局锁时,其消耗的资源会比较多,需要取得所有子段的锁。 4.1.3 用读写分离锁来替换独占锁 165 读操作和读操作可以并行,读写操作才需要加锁。使用读写分离锁(允许多线程同时读)可以减少操作之间相互等待,可以有效的提高性能。 4.1.4 锁分离 165 将读写锁的思想进一步延伸,就是锁分离。例如:LinkedBlockingQueue中,take() 和put() 函数分别实现从队列中取数据和往队列中增加数据的功能。虽然两个函数都对队列做了修改,但LinkedBlockingQueue是基于链表的,两个操作分别位于队列的首端和尾端,两者并不冲突。因此,在JDK的实现中,用两把不同的锁分离了这两个函数,是两者在真正意义上实现了并发。 4.1.5 锁粗化 168

ThreadLocal学习

霸气de小男生 提交于 2020-01-10 15:37:14
import java.util.concurrent.atomic.AtomicInteger; public class ThreadLocalTest { private static AtomicInteger nextHashCode = new AtomicInteger(); //https://www.cnblogs.com/ilellen/p/4135266.html //https://www.jianshu.com/p/640f2c0ac4b0 //https://www.jianshu.com/p/cdb2ea3792b5 private static final int HASH_INCREMENT = 0x61c88647; private static final int INITIAL_CAPACITY = 16; public static void main(String[] args){ for(int i = 0; i < INITIAL_CAPACITY; i++){ System.out.println(getIndex()); } } private static int nextHashCode() { int hashCode = nextHashCode.getAndAdd(HASH_INCREMENT); System.out

Synchronized、Threadlocal、Volatile

感情迁移 提交于 2020-01-09 14:38:28
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