原子变量与CAS算法
原子变量
为了引出原子变量这个概念,我们先看一个例子。
package com.ccfdod.juc; public class TestAtomicDemo { public static void main(String[] args) {
AtomicDemo ad = new AtomicDemo(); for (int i = 0; i < 10; i++) {
new Thread(ad).start();
}
}
} class AtomicDemo implements Runnable {
private int number = 0; @Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " : " + getNumber());
} public int getNumber() {
return number++;
}
}
程序运行结果如下:
Thread-4 : 2
Thread-0 : 6
Thread-2 : 3
Thread-5 : 5
Thread-7 : 4
Thread-3 : 1
Thread-6 : 2
Thread-1 : 0
Thread-9 : 8
Thread-8 : 7
从程序运行结果可以看出,Thread-4和Thread-6执行结果都为2,明显发生了线程安全问题,当然,这种情况是偶然的。那么,出现这种问题的原因是什么呢?
如果你对j = i++;底层是如果实现的,那么这个问题就好理解了。j = i++;底层实现为:
int temp = i;
i = i + 1;
j = temp;
那么很明显,Thread-4(或Thread-6)在执行改操作加1之前,Thread-6(或Thead-4)读到了相同的值。然后都进行加1操作,再打印出来。
对于这类问题,我们可以使用原子变量来解决。在jdk1.5后,java.util.concurrent.atomic包中提供了常用的原子变量。原子变量有一下特性:
- 底层代码使用volatile修饰,保证内存可见性
- CAS(Compare-And-Swap)算法保证数据的原子性
CAS算法
CAS算法是硬件对于并发操作共享数据的支持,CAS包含了三个操作数:
- 内存值V
- 预估值A
- 更新值B
并且,当且仅当V==A时,V=B,否则,将不做任何操作。
在了解了原子变量后,我们使用原子变量修改程序:
class AtomicDemo implements Runnable {
// private int number = 0;
private AtomicInteger number = new AtomicInteger(); @Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " : " + getNumber());
} public int getNumber() {
// return number++;
return number.getAndIncrement();
}
}
原子变量与CAS算法的更多相关文章
- 三、原子变量与CAS算法
原子变量:jdk1.5 后 java.util.concurrent.atomic 包下提供了常用的原子变量: - AtomicBoolean - AtomicInteger - AtomicLong ...
- Java多线程-----原子变量和CAS算法
原子变量 原子变量保证了该变量的所有操作都是原子的,不会因为多线程的同时访问而导致脏数据的读取问题 Java给我们提供了以下几种原子类型: AtomicInteger和Ato ...
- 原子变量与CAS算法小结
CAS算法 CAS(compare-and-swap)是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令,用于管理对共享数据的并发访问. CAS是一种无锁非阻塞算法的实现. CAS ...
- volatile关键字与内存可见性&原子变量与CAS算法
1 .volatile 关键字:当多个线程进行操作共享数据时, 可以保证内存中的数据可见 2 .原子变量:jdk1.5后java.util.concurrent.atomic 包下提供常用的原子变量 ...
- 原子变量与CAS算法(二)
一.锁机制存在的问题 (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换和调度延时,引起性能问题. (2)一个线程持有锁会导致其它所有需要此锁的线程挂起. (3)如果一个优先级高的线程等待一个 ...
- 计算机程序的思维逻辑 (70) - 原子变量和CAS
从本节开始,我们探讨Java并发工具包java.util.concurrent中的内容,本节先介绍最基本的原子变量及其背后的原理和思维. 原子变量 什么是原子变量?为什么需要它们呢? 在理解synch ...
- Java-JUC(三):原子性变量与CAS算法
原子性 并发程序正确地执行,必须要保证原子性.可见性以及有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 原子性:一个操作或多个操作要么全部执行完成且执行过程不被中断,要么就不执行. 可见 ...
- Java编程的逻辑 (70) - 原子变量和CAS
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- juc-2-原子变量与CAS算法
i++的原子性问题 例子 int i=10; i++; 结果 i=10 分析过程 在计算机 底层 会有生成一个临时变量 tem ...
随机推荐
- 使用数组初始化list
ArrayList<String> names = new ArrayList<String>(Arrays.asList("Delete","I ...
- Python获取指定目录下所有子目录、所有文件名
需求 给出制定目录,通过Python获取指定目录下的所有子目录,所有(子目录下)文件名: 实现 import os def file_name(file_dir): for root, dirs, f ...
- 安卓使用Canvas绘制工作日程表
有一个项目要使用工作表,选择使用canvas来绘制.实现显示工作日程的选择,可点击加入和取消,效果图:http://jwzhangjie.com/workplan.gif 自己定义控件FormView ...
- 解决[[NSFileManager defaultManager] contentsOfDirectoryAtPath 方法获取不到数据的bug
在说这个问题之前,必须先解释一下,我们在引入project的时候,xcode会给我们3个选项 1.Copy items if needed 主要是说明,是否要将文件复制到project所在文件夹. 假 ...
- Android View学习Tips
1.Canvas.save()和Canvas.restore() canvas.save();和canvas.restore();是两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的.这里 ...
- java 多线程 day06 threadLocal
import java.util.HashMap;import java.util.Map;import java.util.Random; /** * Created by chengtao on ...
- PyMySQL防止SQL注入
一.SQL注入简介 SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库. 二.SQL注入攻击的总体 ...
- PAT 1126 Eulerian Path[欧拉路][比较]
1126 Eulerian Path (25 分) In graph theory, an Eulerian path is a path in a graph which visits every ...
- oradebug工具使用(转载)
在之前的HangAnalyze 中有使用oradebug命令,在这篇文章里,我们主要是重点看一下这个oradebug命令: Oracle HANGANALYZE 功能诊断 DB hanging htt ...
- Ubuntu学习笔记2-网络部分
Ubuntu server配置IP地址 第一种方法:常规方法 1.登录Ubuntu Server,然后通过“sudo -s” 切换到root用户. 2.输入“cd /etc/network/”,回车 ...