• 原子CAS操作

原子操作指令里,有原子加,原子减,cas到底是什么呢?

首先看一段代码,

bool compare_and_swap(int *accum, int *dest, int newval)
{
if (*accum == *dest) {
*dest = newval;
return true;
} else {
*accum = *dest;
return false;
}
}

cas即是Compare-and-swap,先比较再互换,即修改,意思就是,当reg等oldvalue的时候,将reg设置为newval,这段代码在非原子情况下(多线程)是没用的.

CAS操作,到底有什么威力?

    如果要修改一个变量,在多线程下,应该要加锁,代码是这样的

int num = 0;
void add()
{
lock();
num = num + 123;
unlock();
}

但是如果不要锁,cas来操作??

int num = 0;
void add()
{
int temp;
do
{
temp = num;
}
while (cas(num, temp, temp+123)==true)
}

先让temp目的值=num实际值,如何这个过程中num的值没有改变(temp==num值)则,将新值temp=123 复制给num,跳出循环;

如何第一次发生了变化,那么在读read一次num的值给temp,再次cas比较

  • 2=.研究 cmpxchg指令

cmpxchg是汇编指令
作用:比较并交换操作数.
如:CMPXCHG r/m,  r

==>   cmpxchg  (目的操作数, 源操作数,RAX寄存器)

将累加器AL/AX/EAX/RAX中的值与首操作数(目的操作数)比较,如果相等,第2操作数(源操作数)的值装载到首操作数,zf置1。

如果不等, 首操作数的值装载到AL/AX/EAX/RAX并将zf清0

#include<iostream>
using namespace std;
int main(){
int a=0,b=0,c=0; __asm{
mov eax,100;
mov a,eax
}
cout << "a := " << a << endl;
b = 99;
c = 11;
__asm{
mov ebx,b
cmpxchg c,ebx //将累加器EAX中的值与首操作数(目的操作数)c=11比较 eax=100 != c=11,即不相等,eax=c;
mov a,eax
}
cout << "b := " << b << endl;
cout << "c := " << c << endl;
cout << "a := " << a << endl;
return 0;
}

输出:(如果不等, "首操作数"(c)的值装载到AL/AX/EAX/RAX并将zf清0)

a := 100
b := 99
c := 11
a := 11
#include<iostream>
using namespace std;
int main(){
int a=0,b=0,c=0; __asm{
mov eax,100;
mov a,eax
}
cout << "a := " << a << endl;
b = 99;
c = 99;
__asm{
mov eax,99
mov ebx,777
cmpxchg c,ebx //将累加器EAX=99中的值与首操作数(目的操作数)c=99比较,相等,第2操作数(源操作数)ebx的值装载到首操作数c(c=ebx=777),zf置1。
mov a,eax
}
cout << "b := " << b << endl;
cout << "c := " << c << endl;
cout << "a := " << a << endl;
return 0;
}

输出:(如果相等,第2操作数(源操作数)的值装载到首操作数,zf置1)

a := 100
b := 99
c := 777
a := 99

3=.多线程编程中如何解决数据安全的问题?

package com.tedu;

import java.util.concurrent.atomic.AtomicInteger;

public class MoneyRunnable implements Runnable {
private AtomicInteger sumMoney= new AtomicInteger(100); @Override
public void run() { while (true){ Data.lock.lock();
if(sumMoney.get()>0){
System.out.println(Thread.currentThread().getName() + "获得一元钱");
if (Thread.currentThread().getName().equals("张三")) {
Data.zsMoney++;
} else if (Thread.currentThread().getName().equals("李四")) {
Data.lsMoney++;
} else {
Data.wwMoney++;
}
sumMoney.decrementAndGet();
System.out.println(sumMoney.get()); }else {
System.out.println("钱抢完了");
System.out.println("张三获得了:" + Data.zsMoney);
System.out.println("李四获得了:" + Data.lsMoney);
System.out.println("王五获得了:" + Data.wwMoney);
System.out.println("他们一共获得了:"+(Data.zsMoney+Data.wwMoney+Data.lsMoney));
break;
}
try {
Thread.sleep(400);
}catch (Exception e){e.printStackTrace();} Data.lock.unlock();
} }
}
package com.tedu;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Data {
public static int zsMoney=0; //张三zs
public static int lsMoney=0;//李四
public static int wwMoney=0;//王五 public static int zsMoneyHitNum=0;
public static int lsHitNum=0;
public static int wwHitNum=0; public static Object lockObject1= new Data();
public static Object lockObject2=new Data();
public static Lock lock = new ReentrantLock();
}
package com.tedu;

public class MainApp {
public static void main(String[] args) {
MoneyRunnable my1 = new MoneyRunnable();
Thread t1 = new Thread(my1);
Thread t2= new Thread(my1);
Thread t3 = new Thread(my1);
t1.setName("张三");
t2.setName("李四");
t3.setName("王五");
t1.start();
t2.start();
t3.start(); }
}

这个用sychronized的,和lock的用法一样

while (true) {
/**
* 同步代码块实现数据安全:

* 这里面的this就是一把锁,使用这个类创建的线程使用同一把锁

*/
synchronized (this) {
if (sumMoney > 0) { /**
* sumMoney = sumMoney - 1; 放在前面就不会有问题
*/
// sumMoney = sumMoney - 1;
System.out.println(Thread.currentThread().getName() + "获得一元钱");
if (Thread.currentThread().getName().equals("张三")) {
Data.zsMoney++;
} else if (Thread.currentThread().getName().equals("李四")) {
Data.lsMoney++;
} else {
Data.wwMoney++;
} /**
* sumMoney = sumMoney - 1; 放在后面就会出现数据安全问题(线程安全问题)
*/
sumMoney = sumMoney - 1;
} else {
System.out.println("钱分完了:");
System.out.println("张三获得了:" + Data.zsMoney);
System.out.println("李四获得了:" + Data.lsMoney);
System.out.println("王五获得了:" + Data.wwMoney);
System.out.println("他们一共获得了:" + (Data.zsMoney + Data.wwMoney + Data.lsMoney));
try {
// 防止数据刷的过快,休眠一段时间
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} }
}

atzhang

CAS 原理 应用的更多相关文章

  1. 采用CAS原理构建单点登录

    企业的信息化过程是一个循序渐进的过程,在企业各个业务网站逐步建设的过程中,根据各种业务信息水平的需要构建了相应的应用系统,由于这些应用系统一般是在不同的时期开发完成的,各应用系统由于功能侧重.设计方法 ...

  2. JAVA CAS原理深度分析-转载

    参考文档: http://www.blogjava.net/xylz/archive/2010/07/04/325206.html http://blog.hesey.net/2011/09/reso ...

  3. JAVA CAS原理

    转自: http://blog.csdn.net/hsuxu/article/details/9467651 CAS CAS: Compare and Swap java.util.concurren ...

  4. 【转】JAVA CAS原理深度分析

    java.util.concurrent包完全建立在CAS之上的,没有CAS就不会有此包.可见CAS的重要性. CAS CAS:Compare and Swap, 翻译成比较并交换. java.uti ...

  5. JAVA CAS原理深度分析

    参考文档: http://www.blogjava.net/xylz/archive/2010/07/04/325206.html http://blog.hesey.net/2011/09/reso ...

  6. CAS原理与协议

    SSO英文全称Single Sign On,单点登录. SSO是在多个应用系统中,用户仅仅须要登录一次就能够訪问全部相互信任的应用系统. SSO的解决方式非常多,比方收费的有UTrust.惠普灵动等, ...

  7. JAVA CAS原理深度分析(转)

    看了一堆文章,终于把JAVA CAS的原理深入分析清楚了. 感谢GOOGLE强大的搜索,借此挖苦下百度,依靠百度什么都学习不到! 参考文档: http://www.blogjava.net/xylz/ ...

  8. Java中的CAS原理

    前言:在对AQS框架进行分析的过程中发现了很多CAS操作,因此有必要对CAS进行一个梳理,也便更清楚的了解其原理. 1.CAS是什么 CAS,是compare and swap的缩写,中文含义:比较交 ...

  9. JAVA CAS原理浅谈

    java.util.concurrent包完全建立在CAS之上的,没有CAS就不会有此包.可见CAS的重要性. CAS CAS:Compare and Swap, 翻译成比较并交换. java.uti ...

  10. CAS 原理

    基础模式 1. 访问服务:  客户端发送请求访问应用系统提供的服务资源. 2. 定向认证:  客户端会重定向用户请求到 服务器. 3. 用户认证:用户身份认证. 4. 发放票据: 服务器会产生一个随机 ...

随机推荐

  1. .NET平台系列31:.NET团队送给.NET开发人员的云原生学习资源汇总

    系列目录     [已更新最新开发文章,点击查看详细] .NET Core 启动于2016年,跟K8S同年诞生,既拥有着悠久的历史积累,又集成了当下最新的设计理念,加上.NET团队持续对容器技术的官方 ...

  2. 点分治&cdq分治 总结

    游荡的孤高灵魂不需要羁绊之处. 洛谷题单 点分治 前置芝士 树的重心 树分治 例题略解 P3806 [模板]点分治1 板子题,先暴力找到整棵树的重心,然后先求出重心到各点的距离,进而算出他所在树的各个 ...

  3. DOS命令行(8)——netsh-网络配置命令行工具

    netsh 介绍与语法 netsh(Network Shell) 是一个windows系统本身提供的功能强大的网络配置命令行工具,可用来显示与修改当前正在运行的计算机的网络配置(如:IP地址.网关.D ...

  4. 我的新书《C++服务器开发精髓》终于出版啦

    一.千呼万唤始出来 亲爱的各位读者,我的新书<C++ 服务器开发精髓>终于终于终于与大家见面了,图书如下: 图书的封面设计很精美,当然内容一定不负众望.因出版社老师要求提供一张照片放到封面 ...

  5. ASW 工作流最佳实践(二):使用 ASW 并发调用函数

    在音视频转码.ETL 作业处理.基因数据处理等诸多场景中,我们都可以通过工作流并行调用云函数,将任务进行并行处理,大大提高任务处理的吞吐量,满足应用场景的高实时性.高并发能力. 在<使用 ASW ...

  6. 精尽Spring Boot源码分析 - 文章导读

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  7. 精尽Spring Boot源码分析 - 剖析 @SpringBootApplication 注解

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  8. 【重学Java】可变参数

    可变参数 可变参数[应用] 可变参数介绍 可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了 方法的参数类型已经确定,个数不确定,我们可以使用可变参数 可变参数定义格式 修饰符 ...

  9. nginx反向代理tcp协议的80端口

    需求:内网有一台mqtt协议服务器,需要将外网的mqtt请求通过一台服务器代理到内网的mqtt服务器上.而这台代理服务器不会开放出了80之外的端口,所以只能使用80端口来转发mqtt请求. 步骤:1. ...

  10. springCloud学习05之api网关服务zuul过滤器filter

    前面学习了zuul的反向代理.负载均衡.fallback回退.这张学习写过滤器filter,做java web开发的对filter都不陌生,那就是客户端(如浏览器)发起请求的时候,都先经过过滤器fil ...