2018-8-19

  昨天看到java.util.concurrent.atomic相关的文章,之前有过留意但并未去了解,正好有空学习一下。本人理解atomic包是concurrent子包,当是为并发所用,拿int类型来说,

int i=0; i++; i++并没有做同步写处理,当并发去写时,就可能出现一个线程所写的结果被另外线程所写的结果覆盖,造成最终结果不符合预期,但是如果用synchronized修饰方法,

就是同步方法,与并发处理相冲突,atomic中的类型则可解决此问题,并发时,可理解为各线程尝试修改,不符合预期结果则更新数据重新尝试修改,可避免结果被覆盖情况。

  即可理解为synchronized严格同步为悲观锁,atomic为乐观锁,atomic中的类适合并发编程

以代码来展示:

public class AtomicTest {

    public static int clientTotal=10000;
public static int threadTotal=200;
public static int count=0;
public static AtomicInteger atomicCount=new AtomicInteger(0); public static void main(String[] args) {
try {
test();
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void test() throws InterruptedException {
ExecutorService pool = Executors.newCachedThreadPool();
final Semaphore semphore= new Semaphore(threadTotal);
final CountDownLatch latch=new CountDownLatch(clientTotal);
for(int i=0;i<clientTotal;i++) {
pool.execute(()->{
try {
semphore.acquire();
add();
addAtomic();
semphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
});
}
latch.await();
pool.shutdown();
System.out.println("count--"+count);
System.out.println("atomicCount--"+atomicCount);
}
public static void add() {
count++;
}
public static void addAtomic() {
atomicCount.incrementAndGet();
} }

结果:

count--9998
atomicCount--10000

结果中看出,count不符合预期,部分计算值被覆盖,比如执行一段时间后,当count=1300,线程thread5与线程thread6同时读到这个值,thread5运算写入count=1301,

thread6由于执行运算时count不是最新值,也随之写入count=1301,此时thread6把thread5结果覆盖了,本来两个线程执行完成预期是1302,真实完成后却是1301,

而atomicCount则符合预期。

查看AtomicInteger源码:

private volatile int value;
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
public final int getAndAddInt(Object o, long offset, int delta) {
int v;
do {
v = getIntVolatile(o, offset);
} while (!compareAndSwapInt(o, offset, v, v + delta));
return v;
}

从代码中可看出实现原理,private volatile int value;用volatile修饰value,这样每次写读写都是用最新的值,以下代码

do {

  v = getIntVolatile(o, offset);

} while (!compareAndSwapInt(o, offset, v, v + delta));

即先获得最新的value值,然后比较运算后是否符合预期,符合则写入,不符合则返回false,又重新尝试,compareAndSwap即熟知的CAS,此为原子操作,

即用volatile修饰符来保证最新值,用compareAndSwap方法来保证原子性。

初识java atomic的更多相关文章

  1. 初识Java

    Java是一种简单的.面向对象的.分布式的.解释的.安全的.可移植的.性能优异的多线程语言.它以极强的安全性.平台无关性.硬件结构无关性.语言简洁.面向对象的特点,在网络编程语言中占据了无可比拟的优势 ...

  2. SSH 框架学习之初识Java中的Action、Dao、Service、Model-收藏

    SSH 框架学习之初识Java中的Action.Dao.Service.Model-----------------------------学到就要查,自己动手动脑!!!   基础知识目前不够,有感性 ...

  3. Java 面向对象编程——第一章 初识Java

      第一章    初识Java 1.  什么是Java? Java是一种简单的.面向对象的.分布式的.解释的.安全的.可移植的.性能优异的多线程语言.它以其强安全性.平台无关性.硬件结构无关性.语言简 ...

  4. Personal Learning Path of Java——初识Java

    初识Java 在我个人看来,Java是一门高大上的面向编程语言,这也是Java吸引我的地方.在自学Java之前,我在学校大概学过了一些C语言的知识,在学校学的那点C语言纯属是拿来打基础用的,大概了解了 ...

  5. 初识Java作业

    初识Java作业 一.    填空题 Java技术按照用途不同分为三大版本,分别是JavaSE.     javaEE       和JavaMe Java虚拟机就是一个虚拟的用于执行  .class ...

  6. Java学习笔记心得——初识Java

    初识Java 拿到这本厚厚的<Java学习笔记>,翻开目录:Java平台概论.从JDK到TDE.认识对象.封装.继承与多态...看着这些似懂非懂的术语名词,心里怀着些好奇与担忧,就这样我开 ...

  7. 初识Java程序,编写简单代码?

    Dear All: 初识Java程序,编写简单代码? 首先小编在这里说下我们今天编写Java程序使用的是 eclipse 开发工具! 1.下载eclipse 官网地址:http://www.eclip ...

  8. 初识JAVA语言

    推荐阅读:  我的CSDN  我的博客园  QQ群:704621321 前言        很多游戏开发者可能会有疑问,你会C#,JS,TS,为什么还要初识JAVA呢?有人可能会说,多学点对自己有好处 ...

  9. day01-day02 初识java、注释、变量、变量命名、基本数据类型

    1. 初识java 1) 什么是java java是一门高级的计算机编程语言 2) JDK的安装 2.1) 下载2.2) 安装2.3) 验证 3) 环境变量的配置 3.1) 打开环境变量3.2) 配置 ...

随机推荐

  1. Servlet映射的过程

    1.首先通过上图 locolhost:8080/login.html 访问到这个登录的html页 2 通过html页的 action="LoginServlet" 进行映射,所以填 ...

  2. iframe父页调子页和子页调父页方法

    子页调用父页 window.parent.myChart.resize(); 父页调用子页 $("iframe")[0].contentWindow.myChart.resize( ...

  3. python调用对象属性出错:AttributeError: 'function' object has no attribute '_name_'

    出错如下图所示: 原来是因为把__name__写成_name_, 下图为正确结果:

  4. NDK-C++ support

    1.NDK相关各种可用的C++运行库Android平台自带微型C++运行库(system),NDK提供补充功能的C++运行库(gabi++, stlport, gnustl)运行库 异常支持 RTTI ...

  5. Ubuntu 16.04 搭建 ELK

    1.安装Java JDK sudo apt-get install default-jdk 2.安装Elasticsearch 1.导入Elasticsearch的GPG公钥 wget -qO - h ...

  6. Jquery中复选框选中取消实现文本框的显示隐藏

    标签内容 <div class="box"> 请编写javascript代码,完成如下功能要求:<br /> 1.取消复选款后,要求促销价格.促销开始结束日 ...

  7. Java : java基础(6) 反射与枚举

    类需要经过 加载, 连接, 初始化三个步骤来进行初始化. 加载是把class文件读入内存创建一个class对象, 连接分为三步,第一步是验证是否是正确的结构, 第二步是准备, 为类的静态成员分配内存, ...

  8. vim ,vi总是卡死,终于找到原因了。

    玩了这么多年linux 居然不知道这个..特此记录. 使用vim时,如果你不小心按了 Ctrl + s后,你会发现不能输入任何东西了,像死掉了一般,其实vim并没有死掉,这时vim只是停止向终端输出而 ...

  9. 详解 Python3 正则表达式(二)

    上一篇:详解 Python3 正则表达式(一) 本文翻译自:https://docs.python.org/3.4/howto/regex.html 博主对此做了一些批注和修改 ^_^ 使用正则表达式 ...

  10. 详解PreparedStatement

    详解PreparedStatement /** * PrepareStatement 测试插入数据库 */ /** * 如果使用Statement,那么就必须在SQL语句中,实际地去嵌入值,比如之前的 ...