threadlocal

created a ThreadLocal with key of type [oracle.jdbc.driver.AutoKeyInfo$1]

无人久伴 提交于 2019-12-01 08:07:05
环境: spring4.3, mybatis3.5.2, ojdbc8_8c(oracle 18c jdbc) 调试状态下退出时,提示: 严重 [main] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [oracle.jdbc.driver.AutoKeyInfo$1] (value [oracle.jdbc.driver.AutoKeyInfo$1@10289886]) and a value of type [oracle.jdbc.driver.OracleSql] (value [INSERT INTO 某表 (某字段1, 某字段1) VALUES (?, ?)]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak. 看提示是个插入语句,此表有主键,为整型,没有使用序列,自己生成的一个数值 警告信息中

Java ThreadLocal正确理解

点点圈 提交于 2019-12-01 07:33:08
测试代码如下: 需要注意执行到构造函数和run方法当前的线程ID。以及在何时给ThreadLocal变量塞值。 package com.test.thread.local; public class ThreadLocalTest { //测试ThreadLocal static ThreadLocal<String> threadLocalString = new ThreadLocal<String>(); static class Runer extends Thread{ public Runer(String name) { //构造函数当前线程还是主线程Id System.out.println("Constructor Thread Id: " +Thread.currentThread().getId()); threadLocalString.set("[---Thread Id---]: " +Thread.currentThread().getId() ); } @Override public void run() { //run方法中是新的线程Id System.out.println("Runing fun Thread Id : " + Thread.currentThread().getId()); threadLocalString.set("[-

关于Java ThreadLocal

核能气质少年 提交于 2019-12-01 03:47:45
转自: http://www.appneta.com/blog/introduction-to-javas-threadlocal-storage/ What is ThreadLocal? A simple example As its name suggests, a single instance of ThreadLocal can store different values for each thread independently. Therefore, the value stored in a ThreadLocal instance is specific (local) to the current running Thread, any other code logic running on the same thread will see the same value, but not the values set on the same instance by other threads. (There are exceptions, like InhertiableThreadLocal, which inherits parent thread’s values by default.) Let’s consider this example: We

ThreadLocal终极源码剖析-一篇足矣!

亡梦爱人 提交于 2019-12-01 02:54:42
一、问题复现 1.场景 2个service方法, 方法A中调用方法B。 方法A 是核心业务方法,涉及多张表数据变更,为了保持数据一致,用 spring事务注解 :@Transactional(rollbackFor = Exception.class) 方法B 比较耗时 ,为了不影响核心业务,方法B 用 @Async注解,单独开启一个线程去异步执行 。(方法B在另外一个类里边,不能和A在同一个类)。 2.出错原因 方法B是异步方法,导致 方法A事务还没提交时(不一定出错,具体就看哪个线程执行的快了)方法B就执行了。 3.期望 期望方法A上的大事务commit后再执行方法B。 二、解决方案 1 // 注册事务同步处理 2 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { 3 @Override 4 public void afterCommit() { 5 // 事务提交完毕时,触发:funcB 6 funB(); 7 } 三、原理 提交一个事务同步处理,在事务commit之后执行,具体存放在threadLocal(线程本地变量)中,事务commit时会去threadLocal里边取。源码 afterCommit 是空的,没有任何操作

java类ThreadLocal的理解

谁说胖子不能爱 提交于 2019-11-30 22:27:17
ThreadLocal是什么 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是thread local variable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。线程局部变量并不是Java的新发明,在其它的一些语言编译器实现(如IBM XL FORTRAN)中,它在语言的层次提供了直接的支持。因为Java中没有提供在语言层次的直接支持,而是提供了一个ThreadLocal的类来提供支持,所以,在Java中编写线程局部变量的代码相对比较笨拙,这也许是线程局部变量没有在Java中得到很好的普及的一个原因吧。 ThreadLocal的设计 首先看看ThreadLocal的接口: Java代码 Object get() ; // 返回当前线程的线程局部变量副本 protected Object initialValue(); // 返回该线程局部变量的当前线程的初始值 void set(Object value); // 设置当前线程的线程局部变量副本的值

SimpleDateFormat线程不安全示例及其解决方法

落爺英雄遲暮 提交于 2019-11-30 12:11:06
我们可以用 java.text.SimpleDateFormat 类完成日期的转换和格式化操作,如: import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /** * @author wangmengjun * */ public class SimpleDateFormatExample { private static final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat( "yyyyMMdd"); public Date parseDate(String value) throws ParseException { return SIMPLE_DATE_FORMAT.parse(value); } } import java.text.ParseException; import java.util.Date; /** * * @author wangmengjun * */ public class Main { public static void main(String[] args) throws

ThreadLocal可能引起的内存泄露

老子叫甜甜 提交于 2019-11-30 06:23:28
  threadlocal里面使用了一个存在弱引用的map,当释放掉threadlocal的强引用以后,map里面的value却没有被回收.而这块value永远不会被访问到了. 所以存在着内存泄露. 最好的做法是将调用threadlocal的remove方法.   在threadlocal的生命周期中,都存在这些引用. 看下图: 实线代表强引用,虚线代表弱引用.      每个thread中都存在一个map, map的类型是ThreadLocal.ThreadLocalMap. Map中的key为一个threadlocal实例. 这个Map的确使用了弱引用,不过弱引用只是针对key. 每个key都弱引用指向threadlocal. 当把threadlocal实例置为null以后,没有任何强引用指向threadlocal实例,所以threadlocal将会被gc回收. 但是,我们的value却不能回收,因为存在一条从current thread连接过来的强引用. 只有当前thread结束以后, current thread就不会存在栈中,强引用断开, Current Thread, Map, value将全部被GC回收.   所以得出一个结论就是只要这个线程对象被gc回收,就不会出现内存泄露,但在threadLocal设为null和线程结束这段时间不会被回收的

Netty学习(四)FastThreadLocal

隐身守侯 提交于 2019-11-30 05:57:40
FastThreadLocal 前面介绍过 JDK 的 ThreadLocal , 使用不当的话容易造成内存泄漏最终导致OOM, 并且也有一些地方设计的不够好(相对于接下来要介绍的 FastThreadLocal), 接下来我们就介绍一下 Netty 改进的 FastThreadLocal, 看它到底 Fast 在哪里. (JDK 的 ThreadLocal 的地址: https://www.cnblogs.com/wuhaonan/p/11427119.html ) 同样的, 这回我们根据 FastThreadLocal 的源码对其进行分析. FastThreadLocal#构造方法 FastThreadLocal 有一个标记自己下标的 index , 表明当前 FastThreadLocal 在 InternalThreadLocalMap 存储数据的数组中(Object[] indexedVariables)所处的下标. // 位于 map 中的下标 private final int index; public FastThreadLocal() { index = InternalThreadLocalMap.nextVariableIndex(); } 跟踪 InternalThreadLocalMap.nextVariableIndex(); 的实现可以看到:

反驳:Threadlocal存在内存泄露

淺唱寂寞╮ 提交于 2019-11-30 05:01:18
最近看到网上的一篇文章,分析说明ThreadLocal是如何内存泄露的. 但我不这么认为. ThreadLocal设计的很好,根本不存在内存泄露问题. 本文就结合图和代码的例子来验证我的看法. 网上的代码例子普遍是这样子的: public class Test { public static void main(String[] args) throws InterruptedException { ThreadLocal tl = new MyThreadLocal(); tl.set(new My50MB()); tl=null; System.out.println("Full GC"); System.gc(); } public static class MyThreadLocal extends ThreadLocal { private byte[] a = new byte[1024*1024*1]; @Override public void finalize() { System.out.println("My threadlocal 1 MB finalized."); } } public static class My50MB { private byte[] a = new byte[1024*1024*50]; @Override public

正确理解ThreadLocal

亡梦爱人 提交于 2019-11-30 02:22:44
首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。 各个线程中访问的是不同的对象。 另外,说ThreadLocal使得各线程能够保持各自独立的一个对象,并不是通过ThreadLocal.set()来实现的,而是通过每个线程中的new 对象 的操作来创建的对象,每个线程创建一个,不是什么对象的拷贝或副本。 通过ThreadLocal.set()将这个新创建的对象的引用保存到各线程的自己的一个map中,每个线程都有这样一个map,执行ThreadLocal.get()时,各线程从自己的map中取出放进去的对象,因此取出来的是各自自己线程中的对象,ThreadLocal实例是作为map的key来使用的。 如果ThreadLocal.set()进去的东西本来就是多个线程共享的同一个对象,那么多个线程的ThreadLocal.get()取得的还是这个共享对象本身,还是有并发访问问题。 下面来看一个hibernate中典型的ThreadLocal的应用: private static final ThreadLocal threadSession = new ThreadLocal(); public static Session