• 原子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. 【C++】vector容器的用法

    检测vector容器是否为空: 1 #include <iostream> 2 #include <string> 3 #include <vector> 4 us ...

  2. Docker开启安全的TLS远程连接

    目录 1.1 不安全的远程访问方式 1.1.1 编辑docker.service文件: 1.1.2 重新加载Docker配置生效 1.1.3 警告! 2.1 建立基于TLS数字签名的安全连接 1.1 ...

  3. 实现一个带有动效的 React 弹窗组件

    我们在写一些 UI 组件时,若不考虑动效,就很容易实现,主要就是有无的切换(类似于 Vue 中的 v-if 属性)或者可见性的切换(类似于 Vue 中的 v-show 属性). 1. 没有动效的弹窗 ...

  4. 【复习】Listening and Reading Comprehension

    短对话 M: Why do you declare the news that you're pregnant on your blog directly? W: I'm so excited tha ...

  5. 合肥某小公司面试题:Spring基础

    <对线面试官>系列目前已经连载25篇啦!有深度风趣的系列! [对线面试官]Java注解 [对线面试官]Java泛型 [对线面试官] Java NIO [对线面试官]Java反射 & ...

  6. Java安全之反序列化回显与内存马

    Java安全之反序列化回显与内存马 0x00 前言 按照我个人的理解来说其实只要能拿到Request 和 Response对象即可进行回显的构造,当然这也是众多方式的一种.也是目前用的较多的方式.比如 ...

  7. Vue(11)组件化的基本使用

    前言 有时候有一组html结构的代码,并且这个上面可能还绑定了事件.然后这段代码可能有多个地方都被使用到了,如果都是拷贝来拷贝去,很多代码都是重复的,包括事件部分的代码都是重复的.那么这时候我们就可以 ...

  8. 1、mysql基础入门(1)

    1.mysql基础入门: 1.1.数据库介绍:

  9. 大数据 | 分布式文件系统 HDFS

    HDFS全称Hadoop Distributed File System,看名字就知道是Hadoop生态的一个组件,它是一个分布式文件系统. 它的出现解决了独立机器存储大数据集的压力,它将数据集进行切 ...

  10. external-attacher源码分析(2)-核心处理逻辑分析

    kubernetes ceph-csi分析目录导航 基于tag v2.1.1 https://github.com/kubernetes-csi/external-attacher/releases/ ...