synchronized + volatile + ThreadLocal
线程的共享 synchronized + volatile + ThreadLocal
<1> synchronized 锁住的是对象,当用它来锁住一个类时,实际上也是锁的一个对象。 用了synchronized 就没必要用 volatile, 对于 synchronized 锁住的对象。
<2>最轻量的同步机制 volatile:
特性:只保证可见性。 如定义一个static变量,在主线程中改变了它,分线程不能感知到主线程修改了它。
适用场景:大量读,少量写。
<3>ThreadLocal: 为每一个线程提供变量的副本,实现线程的隔离,每个线程只访问自己的数据。 如:spring在实现事务的时候,TransactionManager, @Transactional.
为什么spring在实现事务的时候要引入ThreadLocal? 答案:每个线程保存自己的连接, 可能调用多次dao, 避免每次调dao都要传递参数connection。
那么是不是可以考虑把 连接 绑定到这个线程上面?? 这就是spring在实现事务的时候使用 ThreadLocal 的原因。 一般用到的方法有: set(T) get() remove()
Thread 类中有一个成员变量, ThreadLocalMap threadLocals。 ThreadLocalMap 以 ThreadLocal<>为键,里面定义了一个 Entry[]数组。 因为一个线程拥有的副本可能有多个,初始大小为16.
class ThreadLocalMap{ static class Entry{} private Entry[] entry; } 通过位运算取到自己的副本。当我们set到ThreadLocal时,实际上是赋值给我们自己的ThreadLocalMap。
当有重复的时候,它会用nextHashCode()再计算。 ThreadLocal不保证变量同步
强引用:Object obj = new Object();
SoftRefence 要发生内存溢出了,强制回收;
弱引用:只要发生gc,就一定会回收; Entry extends WeakRefence. 可以看出ThreadLocal是软引用。
虚引用:最弱。
引发的内存泄露分析:
Stack Heap
ThreadLocalRef ---- ThreadLocal -- [key, value]
/
CurrentThreadRef ---- CurrentThread -- Map
当我们发生gc时,threadLocal被回收,value就无法被引用到了。即发生内存泄漏。 解决办法: threadLocal.remove();
get/set方法中都有调清除,但是不保证一定清除。 但是remove一定清除。 没内存泄露是可能一直在调用 set/get 方法
那它为什么要用弱引用? 如果用强引用,发生内存泄漏就是必然的。因为Map指向的必然。。。。
ThreadLocal 线程不安全??? 因为它可以存共享变量,虽然是不同的引用,但是实例是一个。
synchronized + volatile + ThreadLocal的更多相关文章
- synchronized&volatile
synchronized(JVM实现的锁) 通过这两个关键字,我们可以很容易的实现同步多个任务的行为,可以实现同一时刻,只能有一条线程去访问共享资源 一: 修饰普通方法 多个线程,共同去竞争访问,方法 ...
- Java Synchronized 与 ThreadLocal 异同
同:都是为了线程安全 异:synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问.而ThreadLocal为每一个线程都提供了变量的副本, 使得每个线程在某一时间访问到的并 ...
- java多线程synchronized volatile解析
先简单说说原子性:具有原子性的操作被称为原子操作.原子操作在操作完毕之前不会线程调度器中断.即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行.在Java中,对除了l ...
- 拜托,别再问我怎么自学 Java 了!和盘托出
假如有那么残酷的一天,我不小心喝错了一瓶药,一下子抹掉了我这十多年的编程经验,把我变成了一只小白.我想自学 Java,并且想要找到一份工作,我预计需要 6 个月的时间,前提条件是每天都处于高效率的学习 ...
- paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)
paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象) 1 锁的缺点 2 CAS(Compare ...
- volatile 与 synchronized 区别
在Java中,为了保证多线程读写数据时保证数据的一致性,可以采用两种方式: 同步 如用synchronized关键字,或者使用锁对象. volatile 使用volatile关键字用一句话概括vola ...
- java 里面保留字volatile及其与synchronized的区别
锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility).互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议, ...
- java 语言多线程可见性(synchronized 和 volatile 学习)
共享变量可见性实现的原理 java 语言层面支持的可见性实现方式: synchronized volatile 1. synchronized 的两条规定: 1 线程解锁前,必须把共享变量的最新值刷新 ...
- 13.volatile与synchronized比较
synchronized,volatile都解决了共享变量 value 的内存可见性问题,但是前者是独占锁,同时只能有一个线程调用 get()方法,其他调用线程会被阻塞, 同时会存在线程上下文切换和线 ...
随机推荐
- 【转】oracle远程导入数据库
源地址:http://blog.chinaunix.net/uid-20980141-id-447996.html
- linux线程切换问题
处理器总处于以下状态中的一种: 1.内核态,运行于进程上下文,内核代表进程运行于内核空间: 2.内核态,运行于中断上下文,内核代表硬件运行于内核空间: 3.用户态,运行于用户空间: 一个进程的上下 ...
- docker的常用操作
查看所有的镜像: docker images 查看所有的容器: docker ps -a 查看正在运行的容器: docker ps 移除容器: docker rm -f 容器id 移除镜像: dock ...
- Ant junitreport with Maven
大家可能都知道在Ant里可以使用junit和junitreport两个task来完成对测试结果生成HTML格式的报告. Maven里的Surefire-report的插件只能对Java测试报告支持的比 ...
- XStream -- a simple library to serialize objects to XML and back again
Link :http://xstream.codehaus.org/index.html http://www.cnblogs.com/hoojo/archive/2011/04/22/2025197 ...
- Mysql-proxy代理内网数据库
Mysql-proxy 参考:https://segmentfault.com/q/1010000000394160 情景分析:首先您需要正在使用UCloud云主机(uhoust)以及云数据库(udb ...
- Luogu P5201 [USACO19JAN]Shortcut 最短路树???
最短路树...开眼界了...之前想也没想过.... 先跑出来1到每个点最短路,然后建树时要标记点的入度,否则会多连边...然后深搜时更新新答案就是 #include<cstdio> #in ...
- Java StringBuffer
String是不变类,用String修改字符串会新建一个String对象,如果频繁的修改,将会产生很多的String对象,开销很大.因此java提供了一个StringBuffer类,这个类在修改字符串 ...
- 新磁盘创建lvm并挂载
### .查看硬盘 fdisk -l ### 删除分区 fdisk /dev/sdc ### 按d删除,按w保存并退出 ### 创建pv pvcreate /dev/sdc ### 创建 vg vgc ...
- HikariPool连接池的使用
HikariDataSource datasource= new HikariDataSource( xxxx ); Connection cn = datasource.getConnection( ...