博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AtomicBoolean学习
阅读量:6005 次
发布时间:2019-06-20

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

hot3.png

问题:

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");        }    }}

转载于:https://my.oschina.net/u/1537182/blog/657065

你可能感兴趣的文章
数据库之mysql(数据库编码问题)
查看>>
tomcat中web.xml各配置项的意义
查看>>
Linux下ftp+ssl实现ftps
查看>>
我的友情链接
查看>>
Java基础 - 第一章 计算
查看>>
CentOS7添加用户账户,授权
查看>>
金蝶kis记账王凭证过账要不要要审核
查看>>
Nodejs学习笔记(二):《node.js开发指南》代码中需要注意的几点
查看>>
Ztree异步加载自动展开节点
查看>>
Python Shell 怎样清屏?
查看>>
How to Install Apache CouchDB on CentOS 6 (from Source and EPEL)
查看>>
命令玩转防火墙
查看>>
Centos 6 安装 Gitlab和备份、迁移
查看>>
LINUX学习笔记(四)RAID LVM
查看>>
安装Windows7 原版系统时跳过创建用户 使用administrator的方法
查看>>
zabbix-3.2.11短信报警
查看>>
Python 之 logging日志模块
查看>>
从头学Java_01
查看>>
第一天上班
查看>>
Oracle-day03 中
查看>>