• 原子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. 【TCP/IP】TCP详解笔记

    目录 前言 17. TCP 传输控制协议 17.1 引言 17.2 TCP 服务 17.3 TCP的首部 18. TCP连接的建立与终止 18.1 引言 18.2 连接的建立与终止 18.2.1 建立 ...

  2. 解决java socket在传输汉字时出现截断导致乱码的问题

    解决java socket在传输汉字时出现截断导致乱码的问题 当使用socket进行TCP数据传输时,传输的字符串会编码成字节数组,当采用utf8编码时,数字与字母长度为1个字节,而汉字一般为3个字节 ...

  3. Lin语法(Linq对数据库操作)

    一.Linq语句的应用: var queryAllCustomers = from cust in customers   group cust by cust.City into custGroup ...

  4. 安装nodejs版本模块报错notsup Unsupported platform for n

    使用npm install -g n报错 如果出现npm ERR! notsup Unsupported platform for n@6.7.0: wanted {"os":&q ...

  5. 源代码管理相关命令(Git常用命令、Nuget常用命令、CMD常用命令)

    Git常用命令 源代码工具 工具名称 相关地址 Git Git for Windows VSC Visual Studio Code VSC插件(Gitlen) GitLens - Git super ...

  6. 8、ITSM基本概念(2)

    6.流程和职能: 7.故障管理: (1)故障管理的输入和输出: (2)故障管理的目标: 优先解决影响度大的事件: (3)故障管理的指标: (4)故障管理的流程: 8.问题管理: (1)问题管理的输入和 ...

  7. gRPC四种模式、认证和授权实战演示,必赞~~~

    前言 上一篇对gRPC进行简单介绍,并通过示例体验了一下开发过程.接下来说说实际开发常用功能,如:gRPC的四种模式.gRPC集成JWT做认证和授权等. 正文 1. gRPC四种模式服务 以下案例演示 ...

  8. 剑指offer 1-5

    二维数组中的查找 题目:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中 ...

  9. STM32中的GPIO笔记

    1.GPIO是STM32可控制的引脚,STM32的GPIO被分成很多组,每组有16个引脚.每个GPIO端口包含:2个32位配置寄存器(CRL.CRH),2个32位数据寄存器(IDR.ODR),1个32 ...

  10. 性能基准DevOps之如何提升脚本执行效率

    1.宝路说 宝路最近一直在自我思考:性能基准DevOps工作已经开展一段时间了,目前我们确实已经取得了一些成果,显然这还远远不够.趁闲暇之余跟组员进行了简单的头脑风暴!于是这就有了今天的主题,当然这仅 ...