博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转)利用CAS算法实现通用线程安全状态机
阅读量:5275 次
发布时间:2019-06-14

本文共 1994 字,大约阅读时间需要 6 分钟。

在多线程环境下,如果某个类是有状态的,那我们在使用前,需要保证所有该类的实例对象状态一致,否则会出现意向不到的bug。下面是通用线程安全状态机的实现方法。

public class ThreadSaveState{    private int x;    private int y; private enum State {NEW, INITIALIZING, INITIALIZED}; private final AtomicReference
init = new AtomicReference
(State.NEW); public ThreadSaveState() { }; public ThreadSaveState(int x, int y) { initialize(x, y); } private void initialize(int x, int y) { if (!init.compareAndSet(State.NEW, State.INITIALIZING)) { throw new IllegalStateException("Already initialized"); } this.x = x; this.y = y; //… Do anything else the original constructor did init.set(State.INITIALIZED); } //所有公共接口,都要先调用该方法检测对象完整性 private void checkInit() { if (init.get() != State.INITIALIZED) { throw new IllegalStateException("Uninitialized"); } } //示例公用接口 public int getX() { checkInit(); return x; } //示例公用接口 public int getY() { checkInit(); return y; } }

这种模式利用compareAndSet方法来操作枚举的原子引用,关于compareAndSet方法,其内部是CAS算法,即:Compare and Swap, 翻译成比较并交换,源码如下:

java.util.concurrent包中借助CAS实现了区别于synchronouse同步锁的一种乐观锁,使用这些类在多核CPU的机器上会有比较好的性能.

结合compareAndSet源码我们看下:

/**     * Atomically sets the value to the given updated value     * if the current value {@code ==} the expected value.     * @param expect the expected value     * @param update the new value     * @return true if successful. False return indicates that     * the actual value was not equal to the expected value.     */    public final boolean compareAndSet(V expect, V update) { return unsafe.compareAndSwapObject(this, valueOffset, expect, update); }

根据注释,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,返回True,否则返回false。

再看看我们初始化的代码:

if (!init.compareAndSet(State.NEW, State.INITIALIZING)) {            throw new IllegalStateException("Already initialized");        }

只有当state是New的时候,才开始初始化,否则直接报错。这就保证了对象的完整性,因为如果没有这样的防范机制,万一有个线程要在某个实例上调用initialize(),而另一个线程又要企图使用这个实例,第二个线程就有可能看到这个实例处于不一致的状态。

 

转载:http://blog.csdn.net/qq_27258799

转载于:https://www.cnblogs.com/toosuo/p/7642640.html

你可能感兴趣的文章
Oracle EBS PO 接受入库
查看>>
vue-manage-system 后台管理系统开发总结
查看>>
eclipse乱码解决方法
查看>>
JS与OC中的方法相互调用
查看>>
ASP.NET Core开发-使用Nancy框架
查看>>
沧海一声笑,移动应用的CRASH原因我找到! --记最新款数字化測试“星云測试“的使用攻略...
查看>>
常见浏览器兼容性问题与解决方式
查看>>
推荐系统依据近期浏览进行推荐
查看>>
工厂模式IDAL具体解释
查看>>
UVA - 673 Parentheses Balance
查看>>
数据库编程规范
查看>>
如何修改eclipse里面Android虚拟机的存放路径
查看>>
爬虫作业
查看>>
微软职位内部推荐-Senior Software Engineer
查看>>
c++11 智能指针 unique_ptr、shared_ptr与weak_ptr
查看>>
JavaScript跨域总结与解决办法(转)
查看>>
正则匹配
查看>>
关于架构的思考
查看>>
poj 1149 PIGS【最大流】
查看>>
Array.from()
查看>>