线程安全 如何实现线程安全 volatile ThreadLocal
什么是线程安全
多线程执行某段代码,不对这段代码进行同步处理、线程间的协调,程序运行的结果仍与预期一致,这就是线程安全。
多线程编程的三个核心概念
原子性
: 同数据库事务的原子性,一些操作要么全部成功,要么全部失败,经典的例子就是银行转账。可见性
:多线程并发访问共享变量时,某个线程对共享变量的更新,其他线程能立即看到这个更新。
在java中,对象储存在主内存。每个线程都有自己的工作内存,线程从主内存读取对象到工作内存,执行更新对象操作,立即更新工作内存,但没有立即刷新到主内存,故其他线程仍然读到旧值。
顺序性
: 指程序顺序执行代码中的操作。
编译器、处理器会进行指令重排序,优化代码,以提高处理速度。程序实际的执行顺序可能与代码中的不一样,但编译器、处理器保证结果是一样的。这不会影响单线程的正确性,但会影响多线程的正确性。
要保证多线程程序正确执行,必需保证原子性、可见性、顺序性。
synchronized、ReentrantLock
使用synchronized、ReentrantLock作用于一段代码,同一时刻只能有一个线程能进入这段代码,保证了原子性、顺序性。使用synchronized、ReentrantLock获取到锁,线程更新共享变量后会立即刷新到主内存,其他线程获取到同一个锁时会将缓存失效并从主内存读取新值,保证了可见性。注意是同一个锁才能保证可见性。synchronized、ReentrantLock的性能较差,因为一个线程占有锁,其他线程会阻塞,线程的挂起和唤醒会降低处理速度。
原子操作类
使用AtmoicInteger、AtmoicLong、AtmoicReference来保证原子性,底层使用CAS(compare and swap)。CAS(compare and swap)是非阻塞同步的计算机指令, 它有三个操作数,内存位置、旧的预期值、新值,当内存位置的值与旧的预期值相等时才将新值存入内存位置。对于ABA问题,可使用AtomicStampedReference,通过引入版本号解决。
volatile
volatile能保证可见性和一定程度的顺序性。
变量被volatile修饰时,线程对变量进行写操作时jvm会向处理器发送lock前缀指令,lock前缀指令相当于内存屏障。
内存屏障的功能
- 写操作修改的值会立即刷新到主内存,并设置其他线程的缓存无效,线程读取变量必需从主内存读取新值,保证了可见性。
- 禁止指令重排序,后面的指令不能再内存屏障之前,前面的指令不能再内存屏障之后,保证一定程度的顺序性。
ThreadLocal
每个线程Thread都有一个ThreadLocalMap的变量threadLocals。
ThreadLocal不存储对象,对象存储于每个线程的ThreadLocalMap。ThreadLocal就是对当前线程的ThreadLocalMap进行增删改查。
ThreadLocal中的内存泄露问题
ThreadLocalMap的key是弱引用,这个key就是ThreadLocal对象。
若ThreadLocal变量被设置为null后,且没有强引用指向这个ThreadLocal对象,根据垃圾回收的可达性分析算法,该ThreadLocal对象将被回收,ThreadLocalMap中某个Entry的key就会变为null,不能再使用的value无法释放内存,造成内存泄露。
ThreadLocalMap的补救措施,调用getEntry()、set()、remove()方法会清除key为null的entry。但不调用这三个方法仍然会有内存泄露问题,因此当ThreadLocal使用完时应当remove掉。
如何实现线程安全
互斥同步
: 使用synchronized、ReentrantLock作用于一段代码,同一时刻只能有一个线程能进入这段代码,保证了原子性、可见性、顺序性。非阻塞同步
: CAS(compare and swap)是非阻塞同步的计算机指令, 它有三个操作数,内存位置、旧的预期值、新值,当内存位置的值与旧的预期值相等时才将新值存入内存位置。对于ABA问题,可使用AtomicStampedReference,通过引入版本号解决。无同步
: 使用ThreadLocal将共享变量的可见性限制在线程内部,每个线程维护一个共享变量的副本,线程间相互隔离,不再争用数据。
线程安全 如何实现线程安全 volatile ThreadLocal相关推荐
- 线程执行完之后会释放吗_java多线程并发:CAS+AQS+HashMap+volatile+ThreadLocal,乐分享...
CyclicBarrier.CountDownLatch.Semaphore 的用法 CountDownLatch(线程计数器 ) CountDownLatch 类位于 java.util.concu ...
- java volatile线程可见_volatile-验证线程之间的可见性
由于JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(有些地方称为栈空间),工作内存是每个线程的私有数据区域,而Java内存 模型中规定所有变量都存储在主内存,主内存是共享内 ...
- 在使用线程池时应特别注意对ThreadLocal的使用
使用ThreadLocal并且有线程池时要特别注意,ThreadLocal是以线程为key的,而线程池里面的线程是会被重新利用的,所以如果有使用线程池并且使用ThreadLocal来保存状态信息时要特 ...
- 获取父线程 java_java子线程中获取父线程的threadLocal中的值
我们都知道线程本地变量表也就是ThreadLocal在我们做线程级的数据隔离时非常好用,但是有时候我们会想如何让子线程获取到父线程的ThreadLocal,其实在线程中除了ThreadLocal外还有 ...
- java和线程相关的关键字有哪些_Java中有哪些机制来保证线程安全?synchronized关键字和volatile关键字...
想要解决线程安全问题,首先要知道为什么会造成线程不安全? 在单线程中,我们从来没有提到个线程安全问题,线程安全问题是只出现在多线程中的一个问题.因为多线程情况下有共享数据,每个线程都共享这些数据并对这 ...
- 20200428 线程安全(上)--彻底搞懂volatile关键字
计算机在处理数据的过程中为什么会出现线程不安全的问题. 计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中会涉及到数据的读取和写入.由于程序运行过程中的临时数据是存放在主存(物理内存) ...
- JDK源码系列:子线程如何继承父线程上通过ThreadLocal绑定的数据
上一篇中老吕介绍了ThreadLocal线程数据绑定的原理,今天聊聊父子线程之间如何继承ThreadLocal上维护的数据. 开发过程中异步执行任务有两种情况,第一种情况是 主线程 通过 new Th ...
- java传递父线程对象_父子线程和线程池如何实现threadLocal变量传递
上一次我们看了ThreadLocal的原理和实现,今天我们看看下面几个问题: 1.多线程中父子线程,子线程如何获取父线程的变量?2.主线程和线程池的线程本地副本变量如何实现复用隔离? 一.Inheri ...
- volatile能保持线程安全吗_Java线程安全(volatile synchronized)
总结 volatile不能保证线程安全而synchronized可以保证线程安全.volatile只能保证被其修饰变量的内存可见性,但如果对该变量执行的是非原子操作线程依旧是不安全的.而synchro ...
最新文章
- 面试中多说这么一句话,薪水直接涨5k
- 对话微软黄学东:语音语言技术是镶在 AI 皇冠上的明珠
- xp系统本地服务器环境配置,Windows XP安装Apache环境图文详解Windows服务器操作系统 -电脑资料...
- 个人总结的一个中高级Java开发工程师或架构师需要掌握的一些技能...
- 在真实工作中的编程是怎么样的,与学校里有什么不同?
- C++ limits头文件的用法numeric_limits
- mybatis $和#源代码分析
- go 错误处理总结
- 【记录】Docker安装后出现 Cannot connect to the Docker daemon
- vue避免重新渲染_详解强制Vue组件重新渲染的方法
- Centos/Linux在线环境下载安装包,到离线环境安装,并解决依赖问题
- POJ 2817 状态DP 字符串找最多的重复
- css绘制向左三角形_CSS绘制三角形—border法
- iOS:Tagged Pointer
- 算法图解 PDF 原文内容分享
- DHT爬虫和使用BEP协议完成metadata的下载(BT下载)
- 聊聊FPGA学习与开发板的那些事儿
- 教你如何快速提取视频文案
- HDU-1253-胜利大逃亡
- html 块元素 css,HTML和CSS - 内嵌块元素的问题
热门文章
- 探究Visual Studio项目的当前目录
- NetCore基于Roslyn的动态编译实现
- 在种地这件事上,AI能取代中国人的种族天赋么?
- Redis分布式锁 分段加锁思想实现 分段锁
- C#创建Encoding.ASCII的.txt文件
- 辽宁工程技术大学本科毕业论文答辩和论文选题PPT模板
- 郑州海关销毁近2万张“问题地图” 重约5.3吨
- 朱大能求职之旅-为什么使用消息队列?消息队列有什么优缺点?Kafka/Activemq/Rabbitmq/Rocketmq优缺点对比?
- c语言双截龙_双截龙招式表
- 【hadoop】Hadoop 面试题总结