保障线程安全的设计技术
Java 运行时存储空间
1、可以分为:栈区、堆区、方法区(非堆空间)
2、栈空间
(1)Stack Space
(2)为线程的执行准备一段固定大小的存储空间,每个线程都有独立的线程栈空间,创建线程时就为线程分配栈空间
(3)在线程栈中每调用一个方法,就给方法分配一个栈帧
(4)栈帧用于存储方法的局部变量,返回值等私有数据,即局部变量存储在栈空间中,基本类型变量、引用类型变量值也是存储在栈空间中,引用对象存储在堆中
(5)由于线程栈是相互独立的,一个线程不能访问另外一个线程的栈空间,因此,线程对局部变量、只能通过当前线程的局部变量,才能访问对象进行的操作,具有固定的线程安全性
3、堆空间
(1)Heap Space
(2)存储对象
(3)在 JVM 启动时,分配的一段以动态扩容的内存空间
(4)创建对象时,在堆空间中给对象分配存储空间,实例变量存储在堆空间中
(5)堆空间是多个线程之间可以共享的空间,因此实例变量可以被多个线程共享
(6)多个线程同时操作实例变量可能存在线程安全问题
4、非堆空间
(1)Non-Heap Space
(2)存储常量,类的元数据等
(3)非堆空间在 JVM 启动时,分配的一段可以动态扩容的存储空间
(4)类的元数据包括静态变量,类中方法,方法的元数据(方法名,参数,返回值等)
(5)多个线程可以共享非堆空间,因此访问非堆空间中的静态变量可能存在线程安全问题
无状态对象
1、对象就是数据及对数据操作的封装
(1)对象所包含的数据称为对象的状态(State)
(2)实例变量、静态变量称为状态变量
2、如果一个类的同一个实例,被多个线程共享,并不会使这些线程存储共享的状态,则该类的实例就称为无状态对象(Stateless Object)
3、如果一个类的实例,被多个线程共享,会使这些线程存在共享状态,则该类的实例称为有状态对象
4、实际上,无状态对象就是不包含任何实例变量,也不包含任何静态变量的对象
不可变对象
1、指一经创建它的状态就保持不变的对象,不可变对象具有固有的线程安全性。
2、当不可变对象现实实体的状态发生变化时,系统会创建一个新的不可变对象,如:String 字符串对象
3、一个不可变对象需要满足以下条件
(1)类本身使用 final 修饰,防止通过创建子类来改变它的定义
(2)所有的字段都是 final 修饰,final 字段在创建对象时必须显示初始化,不能被修改
(3)如果字段引用其他状态可变的对象(集合,数组),则这些字段必须是 private
4、应用场景
(1)被建模对象的状态变化不频繁
(2)同时对一组相关数据进行写操作,可以应用不可变对象,既可以保障原子性,也可以避免锁的使用
(3)使用不可变对象作为安全可靠的 Map key,如果 HashMap 的 key 是一个不可变对象,则 hashCode() 的返回值恒定,存储位置是固定的
线程特有对象
1、保障对非线程安全对象的访问的线程安全,避免锁的开销
2、线程特有对象也具有固有的线程安全性
3、ThreadLocal 类相当于线程访问其特有对象的代理,即各个线程通过 ThreadLocal 对象,可以创建并访问各自的线程特有对象
(1)一个线程可以使用不同的 ThreadLocal 实例,创建并访问不同的线程特有对象
(2)ThreadLocal 实例为每个访问它的线程,都关联一个该线程特有的对象,ThreadLocal 实例都有当前线程与特有实例之间的一个关联
装饰器模式
1、基本思想
(1)为非线程安全的对象,创建一个相应的线程安全的外包装对象
(2)客户端代码不直接访问非线程安全的对象,而是访问它的外包装对象
(3)外包装对象、非线程安全对象具有相同的接口,即外包装对象的使用方式,与非线程安全对象的使用方式相同
(4)外包装对象内部通常会借助锁,以线程安全的方式,调用相应的非线程安全对象的方法
2、java.util.Collections 的 synchronizedXXX(xxx)
(1)可以把不是线程安全的 xxx 集合,转换为线程安全的集合
(2)返回值就是指定集合的外包装对象
(3)这类集合又称为同步集合
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战