Java并发编程实战~笔记~章二

1、线程安全要素:对共享、可变状态的访问操作。

所谓状态,是指存储在状态变量(实例或者静态域)中的数据。对象的状态可能包括其他依赖对象的域。状态是一系列变量的集中体现,比如 int[] data; int size; 该对象的状态就包含两个变量。无状态的类一定是线程安全的。

共享是说这个状态将被多个线程访问。

有共享可变状态的类,如果有写操作,那么一定需要对状态进行全面的同步保护。

2、竞态条件(Race Condition):在并发编程中,由于不恰当的执行时序而出现不正确的结果。

常见的竞态条件类型是“先检查后执行(Check-Then-Act)”,比如HashMap的put操作,“如果某个位置空闲,就把新元素设置到这个位置”,在竞态条件下,只有一个元素被正确添加了。

3、复合操作:由多个原子操作组合而成。

比如a++; 这个操作包含了,读取-修改-写入三个原子操作。

比如 if (a!=0) c = b/a; 这个操作至少包含了,判断a不为0-计算b/a-写入c等原子操作。

比如 if (!vector.contains(element)) vector.add(element); ,判断vector不包含element-将element加入vector两个原子操作。

有些类虽然保证了一些方法的原子性,但是组合起来,还是需要额外的加锁机制。

4、程序清单2-8

这里service里面的两处synchronized同步,其实本质上也是“先判断后执行”,但是它是线程安全的。原因不是“先判断后执行”这种方式不需要复合同步,而是这里的业务逻辑要求很宽松,无论谁先执行,谁后执行,其实都不影响。

但是自己这么写程序千万要小心,非常容易出问题。

5、不变性条件:状态变量之间的约束关系,比如这两个变量 int[] data; int size; 之间的关系应该是,data中的数据数目=size。

当类的不变性条件设计多个状态变量时,那么不变性条件中的每个变量都必须由同一个锁来保护。因此可以在单个原子操作中访问或更新这些变量,从而确保不变性条件不被破坏。

6、简单性和性能

当执行时间较长的计算或者可能无法快速完成的操作时(例如,网络I/O),尽量不要持有锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值