惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
Forbes - Security
Forbes - Security
WordPress大学
WordPress大学
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
L
LINUX DO - 热门话题
L
Lohrmann on Cybersecurity
Spread Privacy
Spread Privacy
D
Darknet – Hacking Tools, Hacker News & Cyber Security
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
P
Privacy International News Feed
A
About on SuperTechFans
T
Tailwind CSS Blog
I
InfoQ
S
Securelist
云风的 BLOG
云风的 BLOG
罗磊的独立博客
Recent Announcements
Recent Announcements
T
The Exploit Database - CXSecurity.com
B
Blog RSS Feed
V
Visual Studio Blog
Know Your Adversary
Know Your Adversary
The GitHub Blog
The GitHub Blog
Jina AI
Jina AI
腾讯CDC
Cyberwarzone
Cyberwarzone
有赞技术团队
有赞技术团队
AWS News Blog
AWS News Blog
博客园 - 【当耐特】
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
F
Full Disclosure
S
Secure Thoughts
博客园 - 司徒正美
J
Java Code Geeks
Y
Y Combinator Blog
Google Online Security Blog
Google Online Security Blog
GbyAI
GbyAI
N
News and Events Feed by Topic
Help Net Security
Help Net Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Project Zero
Project Zero
T
Tenable Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Tor Project blog
MyScale Blog
MyScale Blog
Scott Helme
Scott Helme
小众软件
小众软件
K
Kaspersky official blog

博客园 - 凬月

DIV+CSS中标签dl dt dd常用的用法 使用gulp构建一个项目 棋牌游戏服务器架构设计 STM32F103引脚功能定义 STM32的型号的命名规则 关闭jtag保留swd 微信支付----维权接口开发!(转掌眼) 微信支付--入门篇(转掌眼) LoadRunner培训初级教程 [转]在windows环境中使用varnish squid-nginx 基本配置 redis windows下的环境搭建 显示数据库中所有表的记录数 删除MSSQL数据库中所有表 一个带标号的CSS文章列表写法 CSS图片列表 YUI3 CSS Ubuntu 13.10 64位 无法 安装 ia32-libs 解决办法 [转]编译Android源代码常见错误解决办法
(转)利用CAS算法实现通用线程安全状态机
凬月 · 2017-10-09 · via 博客园 - 凬月

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

public class ThreadSaveState{
    private int x;
    private int y;

    private enum State {NEW, INITIALIZING, INITIALIZED};

    private final AtomicReference<State> init = new AtomicReference<State>(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;
        

这种模式利用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