<<java并发编程实践>>读书笔记之委托线程安全


public class NumberRange {

private AtomicInteger lower = new AtomicInteger(0);
private AtomicInteger upper = new AtomicInteger(0);

public void setLower(int i) {
if (i > upper.get()) {
throw new IllegalArgumentException();
}
lower.set(i);
}

public void setUpper(int i) {
if (i < lower.get()) {
throw new IllegalArgumentException();
}
upper.set(i);
}

public boolean isInRange(int i) {
return (i <= upper.get() && i >= lower.get());
}
}


这段代码的意图就是维护一个数值的范围,共享实例变量的线程安全维护委托给AtomicInteger去完成,其实已经这里显然已经力不从心。
只能保证线程间的可见性,但不能保证原子性。如果仅仅只是set当然是没有问题的,但是这里涉及的是符合操作。先判断后set.
假设有一个场景:
lower=2,upper=8
当线程A调用setLower为7的时候,执行set(7),此时有一个线程B调用setUpper(5),由于线程的活跃度不可控,假设A的set动作还刚刚完成,而线程B已经执行到set(5),此时我们维护的数据就已经被破坏。
从上述我们可以看出,这种委托显然是不合理的,因为lower和upper他们是耦合的而不是独立的,这样的对象不能发布,避免用户破坏其不变约束。
于是书中给出了一个总结:
[color=blue] 如果一个类由多个彼此独立的线程安全的状态变量组成,而且类的操作不包含任何无效状态的转换,可以讲线程安全委托给这些状态变量。[/color]
这里既是类NumberRange包含2个线程安全的成员,也不能保证NumberRange就是线程安全的。
这条规则就是适合诸如:Atomic***,AtomicReference,volatile
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值