2020.05.27软件构造听课笔记

本文深入探讨了线程安全的概念及四种实现策略:限制数据共享、使用不可变数据、使用线程安全的数据类型和同步机制。详细分析了每种策略的原理及应用,帮助读者理解如何在多线程环境中避免竞争条件,确保数据的一致性和安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程安全:

线程之间的“竞争条件”:作用于同一个mutable数据上的多个线程,彼此之间存在对该数据的访问竞争并导致interleaving,导致post-condition可能被违反,这是不安全的

线程安全:ADT或方法在多线程中要执行正确

4种线程安全的方法:
1.限制数据共享
2.共享不可变数据
3.共享线程安全的可变数据
4.同步机制:通过锁的机制共享线程不安全的可变数据,变并行为串行

策略1:Confinement
将可变数据限制在单一线程内部,避免竞争
不允许任何其他线程直接读写该数据
核心思想:线程之间不共享mutable数据类型

基本数据类型的局部变量存在线程栈中
局部变量引用了对象,引用保存在栈中,对象本身存储在堆中
对象包含的方法和方法包含的局部变量储存在栈中
对象的成员变量同对象一起存储在堆中,不论成员变量的类型是基本类型还是对象类型(对其他对象的引用)
静态的变量同类的定义一起保存在堆中

堆中的对象可以被所有拥有引用的线程访问
如果两个线程同时调用一个对象上的一个方法,他们都可以访问该对象的成员变量,但是每个线程都有自己的局部变量副本

策略2:Immutability
使用不可变数据类型和不可变引用,避免多线程之间的race condition

不可变的数据通常是线程安全的
对于并发编程,这种隐藏的变化有时是不安全的
如果ADT中使用了beneficent mutation,必须要通过“加锁”机制来保证线程安全

策略3:Using Threadsafe Data Types
如果必须要用mutable的数据类型在多线程之间的数据共享,要使用线程安全的数据类型
一般来说,JDK同时提供两个相同功能的类,一个是threadsafe,另一个不是,原因:threadsafe的类一般性能上受影响

容器类都是线程不安全的
Java API提供了进一步的decorator
对他们的每一个操作嗲用,都以原子方式进行
不会与其他操作interleaving

在使用synchronizeMap(hashMap)之后,不要在把参数hashMap共享给其他线程,不要保留别名,一定要彻底销毁

即使是在线程安全的集合类上,使用iterator也是不安全的
除非使用lock机制

即使是线程安全的collection类,仍可能产生竞争


在代码中以注释的形式增加说明,该ADT采取了什么设计决策来保证线程安全
阐述清楚采取了四种方法中的哪一种?
如果是后两种,还需要考虑对数据的访问都是原子的,不存在interleaving


除非你知道线程访问的所有数据,否则Confinement无法彻底保证线程安全
除非是在ADT内部创建的线程,可以清楚的值访问数据有哪些

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值