threadlocal

java高并发系列 - 第24天:ThreadLocal、InheritableThreadLocal(通俗易懂)

白昼怎懂夜的黑 提交于 2019-11-27 05:08:50
java高并发系列第24篇文章。 环境:jdk1.8。 本文内容 需要解决的问题 介绍ThreadLocal 介绍InheritableThreadLocal 需要解决的问题 我们还是以解决问题的方式来引出 ThreadLocal 、 InheritableThreadLocal ,这样印象会深刻一些。 目前java开发web系统一般有3层,controller、service、dao,请求到达controller,controller调用service,service调用dao,然后进行处理。 我们写一个简单的例子,有3个方法分别模拟controller、service、dao。代码如下: package com.itsoku.chat24; import java.util.ArrayList; import java.util.List; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** * 跟着阿里p7学并发,微信公众号:javacode2018 */

javaSE——补充知识点

雨燕双飞 提交于 2019-11-27 02:22:46
文章目录 补充 1 里氏替换原则 2 注解 3 DTD 4 JDK7,JDK8,JDK9比较 5 ThreadLocal 补充 1 里氏替换原则 里氏替换原则:指的是任何基类可以出现的地方,子类一定可以出现。 定义1:如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都替换成o2时,程序p的行为没有发生变化,那么类型T2是类型T1的子类型。 定义2:所有引用基类的地方必须能透明地使用其子类对象。 通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。 它包含以下4层含义: 1.子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。 2.子类中可以增加自己特有的方法。 3.当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。 4.当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。 ==================================================================== 可以参考一下,设计模式六大原则: http://wiki.jikexueyuan.com/project/java-design-pattern-principle/principle-2.html 2 注解 3 DTD 4 JDK7

ThreadLocal

对着背影说爱祢 提交于 2019-11-26 23:34:17
  在博客园里翻过很多博客,对高手们甚是敬畏,谢谢你们教会了我许多!我也尝试贡献一点自己的学习心得,这是我的第一篇博客,纯原创,谢谢。   这里我想聊的是ThreadLocal,本地线程变量。不单独作概念上的解释了,网上太多。我以一个案例为主线一步步说明为什么我们需要用ThreadLocal?使用ThreadLocal的好处又在哪儿?案例又怎么跟随我们的思维一步步改进。具体的说明都在案例的注释中。 第一步: 第二步: 第三步:  第三步的TransactionManager工具类: 第四步: 第四步中工具类的改进: dao层: 谢谢。 来源: https://www.cnblogs.com/kedong-kou/p/11335290.html

Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析

六眼飞鱼酱① 提交于 2019-11-26 23:28:24
Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 本文内容:读写锁 ReentrantReadWriteLock 的源码分析,基于 Java7/Java8。 阅读建议:虽然我这里会介绍一些 AQS 的知识,不过如果你完全不了解 AQS,看本文就有点吃力了。 目录 使用示例 ReentrantReadWriteLock 总览 源码分析 读锁获取 读锁释放 写锁获取 写锁释放 锁降级 总结 使用示例 下面这个例子非常实用,我是 javadoc 的搬运工: // 这是一个关于缓存操作的故事 class CachedData { Object data; volatile boolean cacheValid; // 读写锁实例 final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { // 获取读锁 rwl.readLock().lock(); if (!cacheValid) { // 如果缓存过期了,或者为 null // 释放掉读锁,然后获取写锁 (后面会看到,没释放掉读锁就获取写锁,会发生死锁情况) rwl

Java多线程编程-(9)-ThreadLocal造成OOM内存溢出案例演示与原理分析

旧时模样 提交于 2019-11-26 17:12:09
前几篇: Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-线程本地ThreadLocal的介绍与使用 Java多线程编程-(4)-线程间通信机制的介绍与使用 Java多线程编程-(5)-使用Lock对象实现同步以及线程间通信 Java多线程编程-(6)-两种常用的线程计数器CountDownLatch和循环屏障CyclicBarrier Java多线程编程-(7)-使用线程池实现线程的复用和一些坑的避免 Java多线程编程-(8)-多图深入分析ThreadLocal原理 案例代码 1、首先看一下代码,模拟了一个线程数为500的线程池,所有线程共享一个ThreadLocal变量,每一个线程执行的时候插入一个大的List集合: import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadLocalOOMDemo { private static final int THREAD_LOOP_SIZE = 500 ;

ThreadLocal内存泄露

旧巷老猫 提交于 2019-11-26 16:49:36
内存泄漏memory leak :是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出。 内存溢出 out of memory :没内存可以分配给新的对象了。 我们知道,线程 Thread对象 中,每个线程对象 内部都有一个的ThreadLocalMap对象 。如果这个对象 存储了多个大对象 ,则可能造成 内存溢出OOM 。为了防止这种情况发生,在ThreadLocal的源码中,有对应的策略,即调用 get()、set()、remove() 方法时,均会清除 ThreadLocal内部的 内存。 ThreadLocal的内部是ThreadLocalMap 。ThreadLocalMap内部是由一个Entry数组组成 。Entry类的构造函数为 Entry(弱引用的ThreadLocal对象, Object value对象)。因为 Entry的key是一个弱引用的ThreadLocal对象 ,所以 在 垃圾回收 之前 ,将会 清除此Entry对象的key 。那么, ThreadLocalMap 中就会出现 key 为 null 的 Entry,就没有办法访问这些 key 为 null 的 Entry 的 value。这些 value 被Entry对象引用,所以value所占内存不会被释放。若在指定的线程任务里面

ThreadLocal为什么会内存泄漏

强颜欢笑 提交于 2019-11-26 16:09:31
1、首先看下ThreadLocal的原理图: 在ThreadLocal的生命周期中,都存在这些引用。 其中,实线代表强引用,虚线代表弱引用; 2、ThreadLocal的实现:每个Thread维护一个ThreadLocalMap映射表,这个映射表的key是ThreadLocal实例本身,value是真正需要存储的Object; 3、也就是说ThreadLocal本身不存储值,它只是作为一个key来让线程从ThreadLocalMap获取value,值得注意的是图中的虚线,表示ThreadLocalMap是使用ThreadLocal的弱引用作为key,其在GC时会被回收; 4、ThreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal没有外部强引用来引用它,那么系统 GC 的时候,这个ThreadLocal势必会被回收,这样一来,ThreadLocalMap中就会出现key为null的Entry,就没有办法访问这些key为null的Entry的value,如果当前线程再迟迟不结束的话,这些key为null的Entry的value就会一直存在一条强引用链:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value永远无法回收,造成内存泄漏。 5、总的来说就是

《java多线程编程核心技术》----ThreadLocal

為{幸葍}努か 提交于 2019-11-26 11:04:44
public class Run { // 类ThreadLocal解决的是变量在不同线程间的隔离性,也就是 不同的线程拥有自己的值, // 不同线程中的值是可以放入ThreadLocal中进行保存的。 public static ThreadLocal t1= new ThreadLocal(); public static void main(String[] args) { if(t1.get()==null){ System.out.println("从未放过值"); t1.set("我的值"); } System.out.println(t1.get()); System.out.println(t1.get()); //从未放过值 //我的值 //我的值 } } // 这里证明对应同一个threadlocal对象,不同的线程使用,线程之间是隔离的 // 线程a和线程b,同时修改threadlocal,不相互影响 public class Run { // 验证线程变量的隔离性 public static ThreadLocal t1 = new ThreadLocal(); public static void main(String[] args) { ThreadA a = new ThreadA(); ThreadB b = new ThreadB(); a

javaSE基础(6)——并发,网络编程,反射

烂漫一生 提交于 2019-11-26 10:15:57
文章目录 1 并发编程 1.1 ThreadLocal 网络编程 反射(基础) 1 并发编程 1.1 ThreadLocal ThreadLocal是一个本地线程副本变量工具类。主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不通的变量值完成操作的场景。 ThreadLocal的 核心机制 : 1.每个Thread线程内部都有一个Map。 2.Map里面存储线程本地对象(key)和线程的变量副本(value) 3.但是,Thread内部的Map是由ThreadLocal维护的,由ThreadLocal负责向map获取和设置线程的变量值。 Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。所以ThreadLocal的应用场合,最适合的是按线程多实例(每个线程对应一个实例)的对象的访问,并且这个对象很多地方都要用到。 参考博客: https://www.jianshu.com/p/98b68c97df9b https://www.cnblogs.com/dolphin0520/p/3920407.html 网络编程 反射(基础) 来源: https://blog.csdn.net/weixin_45044097/article/details

终于明白阿里百度这样的大公司,为什么面试经常拿ThreadLocal考验求职者了

和自甴很熟 提交于 2019-11-25 19:48:56
点击上面↑「 爱开发 」关注我们 每晚10点,捕获技术思考和创业资源洞察 什么是ThreadLocal ThreadLocal是一个本地线程副本变量工具类,各个线程都拥有一份线程私有的数据,线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用。 ThreadLocal提供了线程安全的另一种思路,我们平常说的线程安全主要是保证共享数据的并发访问问题,通过sychronized锁或者CAS无锁策略来保证数据的一致性。 ThreadLocal结构图 从上面的结构图,我们已经窥见ThreadLocal的核心机制: 每个Thread线程内部都有一个Map。 Map里面存储线程本地对象(key)和线程的变量副本(value) Thread内部的Map是由ThreadLocal维护的,由ThreadLocal负责向map获取和设置线程的变量值。 对于不同的线程,每次获取副本值时,别的线程并不能获取到当前线程的副本值,形成了副本的隔离,彼此之间互不干扰。 我们来看个例子。 下面的例子有3个线程[thread#1],[thread#2],[thread#3]修改类变量initValue,当类变量是ThreadLocal的时候3个线程修改的值互不影响,打印的结果都是66 上面的例子3个线程是如果做到同时独立修改变量的,答案就在ThreadLocal的set(),get()方法里面.