文档章节

AtomicBoolean学习

J
 J_Stone
发布于 2016/04/11 23:30
字数 448
阅读 56
收藏 1

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

问题:

1 如何构造,经常使用哪些api?

2 怎么实现的原子操作?

3 示例demo

static {
    try {//1 使用反射获得成员变量"value"
        // 2 得到"value"在内存中的偏移量, 直接操作内存空间,实现对字段value的操作
        valueOffset = unsafe.objectFieldOffset
            (AtomicBoolean.class.getDeclaredField("value"));
    } catch (Exception ex) { throw new Error(ex); }
}
/*
实现AtomicBoolean两个条件:
1 一旦更新,所有的线程读取最新的值
2 多线程同步更新
 */
private volatile int value; //3 volatile使其他线程可见(满足第一个条件)

public AtomicBoolean(boolean initialValue) {
    value = initialValue ? 1 : 0; //4 value的值,要么是1(true),要么是0(false)
}
public AtomicBoolean() { // 默认是false
}
public final boolean compareAndSet(boolean expect, boolean update) { //5 把比较和赋值 一起组合也为原子操作,返回boolean
    int e = expect ? 1 : 0;
    int u = update ? 1 : 0;
    // 6 CAS多线程同步更新。这是个阻塞函数,线程会不断尝试执行,直至成功
    return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
public final void set(boolean newValue) {
    value = newValue ? 1 : 0; //
}


示例demo:

public class BarWorker implements Runnable {

    private static AtomicBoolean exists = new AtomicBoolean(false);

    private String name;

    public BarWorker(String name) {
        this.name = name;
    }

    public void run() {
        // 只允许一个线程去执行,其余线程不执行
        if (exists.compareAndSet(false, true)) {
            System.out.println(name + " enter");
            try {
                System.out.println(name + " working");
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                // do nothing
            }
            System.out.println(name + " leave");
            exists.set(false);//设置为false, 另外一个线程开始执行
        } else {
            System.out.println(name + " give up");
        }
    }
}

如果我不使用AtomicBoolean,实现同样的功能,会怎么做?

public class BarWorker2 implements Runnable {

    private static volatile boolean exists = false;//volatile 使变量可视

    private String name;

    public BarWorker2(String name) {
        this.name = name;
    }

    public void run() {
        // 只允许一个线程去执行,其余线程不执行
        if (exists == false) {   // 这几行组合在一起类似CAS
            synchronized (BarWorker2.class) {
                if (exists == false) {
                    exists = true;
                    System.out.println(name + " enter");
                    try {
                        System.out.println(name + " working");
                        TimeUnit.SECONDS.sleep(2);
                    } catch (InterruptedException e) {
                        // do nothing
                    }
                    System.out.println(name + " leave");
                } else {
                    System.out.println(name + " give up --- 1");
                }
            }
        } else {
            System.out.println(name + " give up --- 2");
        }
    }

}


© 著作权归作者所有

J
粉丝 2
博文 167
码字总数 30214
作品 0
朝阳
私信 提问
java stop graceful

柯里昂
2017/09/15
23
0
Android Architecture Componets BasicSample学习

1.创建工程 所有模块依赖于Google,jencenter,maven仓库 gradle版本:gradle-4.1-milestone-1-all gradle 的Android插件版本在3.0.0-beta7 工程根目录的gradle设置一些变量,表示模块依赖的框...

newtrek
2017/10/06
0
0
Java并发学习(七)-AtomicInteger基本数据类型类

从Java5开始,出现了concurrent并发包,这里主要先介绍atomic包下面的AtomicXXX诸如AtomicBoolean,AtomicInteger,AtomicLong等原子更新类,它们内部实现思想基本一致,这里以AtomicInteger...

anLA_
2017/11/28
0
0
AtomicBoolean 原子布尔值

AtomicBoolean介绍与使用 java.util.concurrent.atomic.AtomicBoolean 继承自java.lang.Object 介绍:在这个Boolean值的变化的时候不允许在之间插入,保持操作的原子性 方法和举例:compare...

王怀楼
06/03
204
0
AtomicBoolean介绍与使用 java.lang.Object

java.lang.Object java.util.concurrent.atomic.AtomicBoolean 继承自Object。 介绍: 在这个Boolean值的变化的时候不允许在之间插入,保持操作的原子性 方法和举例 compareAndSet(boolean ...

vshcxl
2016/12/25
16
0

没有更多内容

加载失败,请刷新页面

加载更多

一篇文章教你轻松使用fastjson

前言 只有光头才能变强。 文本已收录至我的GitHub精选文章,欢迎Star:https://github.com/ZhongFuCheng3y/3y JSON相信大家对他也不陌生了,前后端交互中常常就以JSON来进行数据交换。而有的...

Java3y
32分钟前
4
1
分组功能(tapply,by,aggregate)和* apply系列

每当我想在R中做“ map” py任务时,我通常都会尝试在apply系列中使用一个函数。 但是,我从未完全理解它们之间的区别-{ sapply , lapply等}如何将函数应用于输入/分组输入,输出将是什么样...

javail
32分钟前
4
0
PHP环境搭建之单独安装

还在使用PHP集成环境吗?教你自定义搭建配置PHP开发环境,按照需求进行安装,安装的版本可以自己选择,灵活性更大。 目录: 1. 安装Apache 2. 安装PHP 3. 安装MySQL 4. 安装Composer 观看:h...

不冷的大叔
44分钟前
4
0
为什么JavaScript变量会以美元符号开头?

我经常看到JavaScript带有以美元符号开头的变量。 您何时/为什么选择以这种方式为变量添加前缀? (我不是在问您在jQuery和其他语言中看到的$('p.foo')语法,而是普通变量,例如$name和$orde...

技术盛宴
48分钟前
4
0
TCP 三次握手

https://my.oschina.net/u/4198159/blog/3141874

奋斗的小牛
57分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部