/**
* NumberRange
* <p/>
* Number range class that does not sufficiently protect its invariants
*
* @author Brian Goetz and Tim Peierls
*/ public class NumberRange {
// INVARIANT: lower <= upper
private final AtomicInteger lower = new AtomicInteger(0);
private final AtomicInteger upper = new AtomicInteger(0); public void setLower(int i) {
// Warning -- unsafe check-then-act
if (i > upper.get())
throw new IllegalArgumentException("can't set lower to " + i + " > upper");
lower.set(i);
} public void setUpper(int i) {
// Warning -- unsafe check-then-act
if (i < lower.get())
throw new IllegalArgumentException("can't set upper to " + i + " < lower");
upper.set(i);
} public boolean isInRange(int i) {
return (i >= lower.get() && i <= upper.get());
}
}

NumberRange既不能使用指向不可变对象的volatile引用来安全地实现上界和下界,也不能使用原子的整数来保存这两个边界。由于有一个不变性条件限制了两个数值,并且它们无法在同时更新时还维持该不变性条件,因此如果在数值范围类中使用volatile引用或者多个原子整数,那么将出现不安全的“先检查再运行”操作序列。

可以将OneValueCache中的技术与原子引用结合起来,它在更新上界或下界时能避免NumberRange的竞态条件。

/**
* CasNumberRange
* <p/>
* Preserving multivariable invariants using CAS
*
* @author Brian Goetz and Tim Peierls
*/
@ThreadSafe
public class CasNumberRange {
@Immutable
private static class IntPair {
// INVARIANT: lower <= upper
final int lower;
final int upper; public IntPair(int lower, int upper) {
this.lower = lower;
this.upper = upper;
}
} private final AtomicReference<IntPair> values = new AtomicReference<IntPair>(new IntPair(0, 0)); public int getLower() {
return values.get().lower;
} public int getUpper() {
return values.get().upper;
} public void setLower(int i) {
while (true) {
IntPair oldv = values.get();
if (i > oldv.upper)
throw new IllegalArgumentException("Can't set lower to " + i + " > upper");
IntPair newv = new IntPair(i, oldv.upper);
if (values.compareAndSet(oldv, newv))
return;
}
} public void setUpper(int i) {
while (true) {
IntPair oldv = values.get();
if (i < oldv.lower)
throw new IllegalArgumentException("Can't set upper to " + i + " < lower");
IntPair newv = new IntPair(oldv.lower, i);
if (values.compareAndSet(oldv, newv))
return;
}
}
}

《Java并发编程实战》笔记-OneValueCache与原子引用技术的更多相关文章

  1. Java并发编程实战.笔记十一(非阻塞同步机制)

    关于非阻塞算法CAS. 比较并交换CAS:CAS包含了3个操作数---需要读写的内存位置V,进行比较的值A和拟写入的新值B.当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不 ...

  2. 多线程-java并发编程实战笔记

    线程安全性 编写线程安全的代码实质上就是管理对状态的访问,而且通常都是共享的,可变的状态. 一个对象的状态就是他的数据,存储在状态变量中,比如实例域或静态域.所谓共享是指一个对象可以被多个线程访问:所 ...

  3. Java并发编程实战笔记—— 并发编程1

    1.如何创建并运行java线程 创建一个线程可以继承java的Thread类,或者实现Runnabe接口. public class thread { static class MyThread1 e ...

  4. Java并发编程实战笔记

    如果当多个线程访问同一个可变的状态变量时没有使用合适的同步,那么程序就会出现错误.有三种方式可以修复这个问题: i.不在线程之间共享该状态变量 ii.将状态变量修改为不可变的变量 iii.在访问状态变 ...

  5. java并发编程实战笔记---(第三章)对象的共享

    3.1 可见性 synchronized 不仅实现了原子性操作或者确定了临界区,而且确保内存可见性. *****必须在同步中才能保证:当一个线程修改了对象状态之后,另一个线程可以看到发生的状态变化. ...

  6. Java并发编程实战 第15章 原子变量和非阻塞同步机制

    非阻塞的同步机制 简单的说,那就是又要实现同步,又不使用锁. 与基于锁的方案相比,非阻塞算法的实现要麻烦的多,但是它的可伸缩性和活跃性上拥有巨大的优势. 实现非阻塞算法的常见方法就是使用volatil ...

  7. java并发编程实战笔记---(第五章)基础构建模块

    . 5.1同步容器类 1.同步容器类的问题 复合操作,加容器内置锁 2.迭代器与concurrentModificationException 迭代容器用iterator, 迭代过程中,如果有其他线程 ...

  8. java并发编程实战笔记---(第四章)对象的组合

    4.1设计线程安全的类 包含三个基本要素: 1.找出构成对象状态的所有变量 2.找出约束状态变量的不变性条件 2.简历对象状态的并发访问管理策略 对象的状态: 域 基本类型所有域, 引用类型包括被引用 ...

  9. Java并发编程实战笔记—— 并发编程2

    1.ThreadLocal Java中的ThreadLocal类可以让你创建的变量只被同一个线程进行读和写操作.因此,尽管有两个线程同时执行一段相同的代码,而且这段代码又有一个指向同一个ThreadL ...

随机推荐

  1. innerHTML与innerText功能的强大

    例: <div id="study"> <span style="color:red">学习</span>study < ...

  2. java-多态中成员访问特点-父类引用指向子类对象

    多态前提: - 要有继承关系. - 要有方法重写. - 要有父类引用指向子类对象. 1.成员变量:编译看左边(父类),运行看左边(父类) 2.成员方法:编译看左边(父类),运行看右边(子类),动态绑定 ...

  3. ionic局部刷新页面与刷新整个页面

    1.全局刷新,禁用缓存: 在app.js中设置cach:false,如下: .state('material', { url: '/material', cache:false, templateUr ...

  4. LeetCode - Most Frequent Subtree Sum

    Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a ...

  5. 【BZOJ3144】【HNOI2013】切糕

    总算做了一道2011以后的省选题了……原题: 图片题面好评! P,Q,R≤40,0≤D≤R,给出的所有的不和谐值不超过1000. 文本样例好评! 恩这个是听妹主席讲过后会写的,首先把每个点拆成链,那么 ...

  6. MySQL Execution Plan--数据排序操作

    MySQL数据排序 MySQL中对数据进行排序有三种方式:1.常规排序(双路排序)2.优化排序(单路排序)3.优先队列排序 优先队列排序使用对排序算法,利用堆数据结构在所有数据中取出前N条记录. 常规 ...

  7. Cassandra如何保证数据最终一致性

    Cassandra如何保证数据最终一致性:1.逆熵机制(Anti-Entropy)使用默克尔树(Merkle Tree)来确认多个副本数据一致,对于不一致数据,根据时间戳来获取最新数据. 2.读修复机 ...

  8. 使用apache cxf实现webservice服务

    1.在idea中使用maven新建web工程并引入spring mvc,具体可以参考https://www.cnblogs.com/laoxia/p/9311442.html; 2.在工程POM文件中 ...

  9. perventDefault, stopPropagation, stopImmediatePropagation 三者的区别

    event有三种特别容易混淆的方法, 用来阻止默认事件的发生 1.  e.preventDefault(); 2. e.stopPropagation(); 3. e.stopImmediatePro ...

  10. 安装mysql时包冲突解决方法

    报错信息如下: 解决办法: 在卸载代码上加上不检查关联信息即可(rpm -ev mysql-libs-5.1.73-7.el6.x86_64 --nodeps) 检查服务器是否还有mysql安装包:r ...