5 并发之AtomicIntegerArray
    该类是Java对Integer数组支持的原子性操作;在认识这个类之前我们先来看一个方法,这个方法是Integer类中的;
 public static int numberOfLeadingZeros(int i) {}
看看官方的解释吧:返回具有至多单个 1 位的 int 值,在指定的 int 值中最高位(最左边)的 1 位的位置。
看完官方的解释大家知道了吧;哈哈,说实话其实我也没能理解;但是这并不妨碍我们对该方法的使用;
该方法直译过来就是抵达0位置的个数:
先来看一段代码吧:
public class IntegerArrayTest {
public static void main(String[] args) {
Integer a=1;
Integer b=13;
Integer c=25;
/**
* 0000 0000 0000 0000 0000 0000 0000 0000
* 0000 0000 0000 0000 0000 0000 0000 0001 0的个数为31 1
* 0000 0000 0000 0000 0000 0000 0000 1101 0的个数为28 13
* 0000 0000 0000 0000 0000 0000 0001 1001 0的个数为27 25
* a的二进制为=1 最左边开始数起连续0的个数为31
* b的二进制为=1101 最左边开始数起连续0的个数为28
* c的二进制为=11001 最左边开始数起连续0的个数为27
*/
System.out.println("a的二进制为="+Integer.toBinaryString(a)+" 最左边开始数起连续0的个数为"+Integer.numberOfLeadingZeros(a));
System.out.println("b的二进制为="+Integer.toBinaryString(b)+" 最左边开始数起连续0的个数为"+Integer.numberOfLeadingZeros(b));
System.out.println("c的二进制为="+Integer.toBinaryString(c)+" 最左边开始数起连续0的个数为"+Integer.numberOfLeadingZeros(c)); }
} public class AtomicIntegerArray implements java.io.Serializable {
private static final long serialVersionUID = 2862133569453604235L; private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final int base = unsafe.arrayBaseOffset(int[].class);
private static final int shift;
private final int[] array; static {
int scale = unsafe.arrayIndexScale(int[].class);
if ((scale & (scale - 1)) != 0)
throw new Error("data type scale not a power of two");
shift = 31 - Integer.numberOfLeadingZeros(scale);
}
}
 
在看上述的代码之前,我先来说一个问题:
    在AutomicInteger类中,value的值是使用了volatile修饰的;会对所有的线程立即可见;但是本身又不可以保证原子性的操作;那么为什么还要在该类中使用这个关键字呢?
    在这里我需要做一个补充说明;看如下的代码所示(是AutomicIntegerArray中的方法):

   /**
* 原子性的设置一个值
*/
public final void set(int i, int newValue) {
unsafe.putIntVolatile(array, checkedByteOffset(i), newValue);
}

下面的源码是AutomicInteger类中的set()方法

 /**
* 原子性的设置一个值
*/
public final void set(int newValue) {
value = newValue;
}
 
大家看到了吧,两个方法的本质是一样的,第一个方法使用了CAS算法,并且获原子性的设置了这个数组中元素的值;之所以使用volatile是对其它线程立马可见;这个才是最重要的原因;而对于lazySet()方法而言,是没有使用volatile关键字的;因为它对其他线程是属于赖设置的;也就是不能马上被其他线程可见;也就是说可以变量共享,但是使用了volatile将失去JVM的优化作用;原子性操作我认为大多数操作或者读的操作没有使用volatile的关键是读可以多线程共享,写不是共享的;其实CAS算法设计的就是乐观锁的思想;
public static void automicIntegerArray() {
/**
* 创建一个原子性的数组,长度为5
*/
AtomicIntegerArray atomicArray = new AtomicIntegerArray(5);
/**
* 设置第一个元素的值为5
*/
atomicArray.set(0, 5);
/**
* 第一个元素减去1
*/
int current = atomicArray.decrementAndGet(0);
System.out.println("current = " + current);//current = 4
}
看AutomicIntegerArray的构造器
/**
* 创建一个原子性整※数组,并且长度为length;而且初始值都为0
* elements initially zero.
*/
public AtomicIntegerArray(int length) {
array = new int[length];
}
    
 
 
 
 
 
 
 
 
 

并发之AtomicIntegerArray的更多相关文章

  1. 并发之java.util.concurrent.atomic原子操作类包

    15.JDK1.8的Java.util.concurrent.atomic包小结 14.Java中Atomic包的原理和分析 13.java.util.concurrent.atomic原子操作类包 ...

  2. 微信公众号开发之VS远程调试

    目录 (一)微信公众号开发之VS远程调试 (二)微信公众号开发之基础梳理 (三)微信公众号开发之自动消息回复和自定义菜单 前言 微信公众平台消息接口的工作原理大概可以这样理解:从用户端到公众号端一个流 ...

  3. Android混合开发之WebViewJavascriptBridge实现JS与java安全交互

    前言: 为了加快开发效率,目前公司一些功能使用H5开发,这里难免会用到Js与Java函数互相调用的问题,这个Android是提供了原生支持的,不过存在安全隐患,今天我们来学习一种安全方式来满足Js与j ...

  4. Android混合开发之WebView与Javascript交互

    前言: 最近公司的App为了加快开发效率选择了一部分功能采用H5开发,从目前市面的大部分App来讲,大致分成Native App.Web App.Hybrid App三种方式,个人觉得目前以Hybri ...

  5. UWP开发之Template10实践二:拍照功能你合理使用了吗?(TempState临时目录问题)

    最近在忙Asp.Net MVC开发一直没空更新UWP这块,不过有时间的话还是需要将自己的经验和大家分享下,以求共同进步. 在上章[UWP开发之Template10实践:本地文件与照相机文件操作的MVV ...

  6. UWP开发之Template10实践:本地文件与照相机文件操作的MVVM实例(图文付原代码)

    前面[UWP开发之Mvvmlight实践五:SuspensionManager中断挂起以及复原处理]章节已经提到过Template10,为了认识MvvmLight的区别特做了此实例. 原代码地址:ht ...

  7. UWP开发之Mvvmlight实践七:如何查找设备(Mobile模拟器、实体手机、PC)中应用的Log等文件

    在开发中或者后期测试乃至最后交付使用的时候,如果应用出问题了我们一般的做法就是查看Log文件.上章也提到了查看Log文件,这章重点讲解下如何查看Log文件?如何找到我们需要的Packages安装包目录 ...

  8. Android混合开发之WebView使用总结

    前言: 今天修改项目中一个有关WebView使用的bug,激起了我总结WebView的动机,今天抽空做个总结. 混合开发相关博客: Android混合开发之WebView使用总结 Android混合开 ...

  9. Android Studio快速开发之道

    概述 现如今开发越来越追求效率和节奏,节省出时间做更多的事情,除了开发技术上的封装等,开发工具的使用技巧也是很重要的,今天就根据自己的经验来给大家介绍一下Android Studio快速开发之道. P ...

随机推荐

  1. get传输时,会将加号+ 转换为空格

    解决办法: 前端: 替换加号为 ‘%2B’, 后端: 直接接收即可.

  2. java网络编程TCP传输—流操作—拿到源后的写入动作

    在网络编程中的TCP传输里,拿到Socket的源后,应该怎么进行读写操作呢,下面我列举了两种方法,希望大家帮忙补充···· 1.利用byte数组作为一个缓冲区进行读写 客户端上传 //获取socket ...

  3. 剑指offer-第六章面试中的各项能力(二叉树的深度)

    题目:1:输入一个二叉树,求二叉树的深度.从根节点开始最长的路径. 思路:我们可以考虑用递归,求最长的路径实际上就是求根节点的左右子树中较长的一个然后再加上1. 题目2:输入一颗二叉树的根节点,判断该 ...

  4. LeetCode Find Duplicate File in System

    原题链接在这里:https://leetcode.com/problems/find-duplicate-file-in-system/description/ 题目: Given a list of ...

  5. maven打war包后无法依赖本地工程的jar包,造成debug时跳到class文件而不是本地java文件

    问题现象:项目结构如下 growup-service | - - - - - -growup-api | - - - - - -growup-core | - - - - - -growup-war ...

  6. 本地连接远程环境mysql报错:Host'xxx.xxx.xxx.xxx' is not allowed to connect to this MySQL server

    问题现象:本机连接远程环境的mysql数据库报错,提示本机ip无法连接到mysql服务器. 问题原因:本机对远程mysql数据库没有访问权限. 解决方法:在远程mysql数据库添加本机ip的访问权限: ...

  7. EMI (电磁干扰)

    EMI是指电子产品工作会对周边的其他电子产品造成干扰,与此关联的还有EMC规范.是电子电器产品经常遇上的问题.干扰种类有传导干扰和辐射干扰. 电磁干扰(Electromagnetic Interfer ...

  8. 使用Spring和Tomcat发布CXF REST WebService

    与发布SOAP WS一样, 同样需要在web.xml文件中配置CXFServlet: <!--cxf的Servlet--> <servlet> <servlet-name ...

  9. PL/Sql developer安装,设置

    安装PL/Sql developer,和安装出现错误(oracle client not properly installed),pl/sql中文乱码 下载安装plsql_dev(文末有64位的百度云 ...

  10. 【转】 Pro Android学习笔记(九二):AsyncTask(1):AsyncTask类

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 在Handler的学习系列中,学习了如何h ...