当前位置: 首页 > news >正文

当前主流网站开发技术确定网站设计公司简报

当前主流网站开发技术,确定网站设计公司简报,网站icp备案 技术负责人,浙江艮威水利建设有限公司网站上文我们认识了许许多多的锁,此篇我们的CAS就是从上文的锁策略开展的新概念,我们来一探究竟吧 1. 什么是CAS? CAS: 全称Compare and swap,字⾯意思:“比较并交换”,⼀个CAS涉及到以下操作: 我们假设内存中…

上文我们认识了许许多多的锁,此篇我们的CAS就是从上文的锁策略开展的新概念,我们来一探究竟吧

1. 什么是CAS?

CAS: 全称Compare and swap,字⾯意思:“比较并交换”,⼀个CAS涉及到以下操作:
我们假设内存中的原数据V,旧的预期值A,需要修改的新值B。

  1. 比较A与V是否相等。(比较)
  2. 如果比较相等,将B写入V。(交换)
  3. 返回操作是否成功。

CAS伪代码
下面写的代码不是原子的,真实的CAS是⼀个原子的硬件指令完成的.这个伪代码只是辅助理解CAS的工作流程.

while{boolean CAS(address, expectValue, swapValue) {if (&address == expectedValue) {&address = swapValue;return true;}return false;}
}

说明:

  1. address: 表示要修改的内存地址
  2. expectValue: 预期值
  3. swapValue:要设置的新值

执行流程:

  1. 用一个预期值去和内存中的值做比较
  2. 如果预期值与内存中的值相等,就用新的值更新内存中的值
  3. 如果预期值与内存中的值不相等,就用进入下一次比较

我们前面学习过的线程安全问题是由于CPU的随机调度导致的,我们的处理方法是给有关修改共享变量的代码块加了synchronize关键字,保证了原子性,解决了线程安全问题,
那么问题来了,
为什么我们看到的CAS伪代码并没有保证原子性,那么他是如何保证原子性的呢??

我们从一段例子来讲解:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

总结:

  1. CAS对应的是硬件指令cmpxchg从CPU做了原子性支持,与LOCK 、UNLOCK 指令同地位
  2. CAS操作每次读取(LOAD)数据是从主内存中读取,并没有对应的工作内存
  3. 自旋锁是通过while把CAS进行包裹,让CAS没有成功的时候不停的执行,直到成功执行为止
  4. CAS是一个真正的指令,JVM调用了本地方法之后,对应的CAS指令会在CPU上执行
    执行中LOAD数据会访问主内存

2. CAS实现自旋锁

基于CAS实现更灵活的锁,获取到更多的控制权.
自旋锁伪代码:

public class SpinLock {private Thread owner = null;public void lock(){// 通过CAS 看当前锁是否被某个线程持有.  
// 如果这个锁已经被别的线程持有, 那么就⾃旋等待.  
// 如果这个锁没有被别的线程持有, 那么就把owner 设为当前尝试加锁的线程.  
}}while(!CAS(this.owner, null, Thread.currentThread())){}public void unlock (){this.owner = null;}

3. JDK中基于CAS实现的原子类

说明:

  1. JDK中提供了CAS实现的原子类,我们举其中一种AtomicInteger类来说明
    在这里插入图片描述
  2. 我们调用其中的方法getAndIncrement()
//自增 ++i
atomicInteger.getAndIncrement();
  1. 我们发现getAndIncrement()方法本质是getAndIncrement()
public final int getAndIncrement() {return U.getAndAddInt(this, VALUE, 1);
}
  1. 其中调用了Unsafe这个类的方法,是JDK内部的工具类,不建议外部程序员直接调用
private static final Unsafe U = Unsafe.getUnsafe();
//获取内存中字段在对象中的偏移地址private static final long VALUE= U.objectFieldOffset(AtomicInteger.class, "value");
//1. o表示原子类对象
//2. offset表示内存中字段在对象中的偏移地址
//3. delta表示传入的值
public final int getAndAddInt(Object o, long offset, int delta) {int v;do {//v是CAS操作之前获取的预期值v = getIntVolatile(o, offset);} while (!weakCompareAndSetInt(o, offset, v, v + delta));//while不停的自旋return v;}
   public final boolean weakCompareAndSetInt(Object o, long offset,//内存地址int expected,//预期值int x) {//要设置的值return compareAndSetInt(o, offset, expected, x);//最后调用compareAndSetInt()方法}
//native表示本地方法,即对应了一条CAS指令cmpxchg
public final native boolean compareAndSetInt(Object o, long offset,int expected,int x);
  1. 图解如下:
    在这里插入图片描述

4. CAS的ABA问题

首先我们要知道什么是ABA问题???

ABA的问题:
假设存在两个线程t1和t2.有一个共享变量value,初始值为A.
接下来,线程t1想使用CAS把value值改成Z,那么就需要
先读取value的值,记录到oldValue变量中.
使用CAS判定当前value的值是否为A,如果为A,就修改成Z.
但是,在t1执行这两个操作之间,t2线程可能把value的值从A改成了B,又从B改成了A

举个例子: 今天是疯狂星期四,我和我的女友共用一个小荷包吃饭,我和她说如果小荷包里面有100元 (A状态) 晚上6点就点KFC吃,我怕她忘记了,我就先自己点了,此时,小荷包余额为50元 (B状态) 然后我的朋友疯狂星期四V我50,小荷包的钱又变回了100 (A状态),她再点的时候,发现小荷包还是100元,她就再点了一份,就导致多点了一份KFC

那么我们该如何解决ABA问题呢??
在点KFC的例子当中,我们可以让他查看一下消费记录(版本号),此时的100元是否是开始的100元,
由此可得,我们可以可以给value数据加上一个版本号,当线程2要修改时,不仅要value要符合预期值,同时版本号也要符合
即:
CAS操作在读取旧值的同时,也要读取版本号.
真正修改的时候,

  • 如果当前版本号和读到的版本号相同,则修改数据,并把版本号+1.
  • 如果当前版本号高于读到的版本号.就操作失败(认为数据已经被修改过了).

版本号可以用自增的数值,也可以用随机的UUID,也可以使用时间戳

System.out.println(UUID.randomUUID());

生成随机数:
在这里插入图片描述

http://www.yayakq.cn/news/364877/

相关文章:

  • 无锡网站推广电话网站建设仿站
  • 网站刷链接怎么做安平谁做网站好
  • 给网站做认证个人网站建设的流程
  • 手机微网站开发教程烟台cms建站模板
  • 剖析材料范文哪个网站做的好视频号认证需要多少钱
  • 国外的服务器网站怎么去找做网站的
  • 网站格式有哪些山东省建设职业教育集团网站
  • ppt制作软件模板网站网站建设管理案例实训报告
  • 浙江省建设质量工程协会网站网站代做多长时间
  • 使用div建设的网站wordpress前端验证
  • 西安住房建设局网站青岛新公司网站建设推广
  • 怎么可以找到做公益的网站中山网站建设价位
  • 很看好未来做生鲜的网站看网站用什么软件
  • 广西住房和城乡建设厅官方网站营销型网站的网址
  • 如何给网站做地图山东省建设厅定额网站
  • 什么网站源码做分类信息网站好seo网站推广与优化方案
  • 网站模块建设方案电商网站wordpress
  • 门户网站时代网站优化内链怎么做
  • 青海政企网站建设自己开发一款游戏怎么做
  • 外贸seo站陕西省建设厅证网站号多少
  • 网站虚拟主持人怎么搭建wordpress
  • 广州达美网站建设网站地图 用户体验
  • 找公司做网站注意什么做网站去哪里
  • 网站的优势与不足安徽移动互联网开发
  • 网站推广攻略来个网站吧好人一生平安2021
  • 外贸数据分析网站外贸自建站源码
  • 做网站 博客如何查询网站空间大小
  • 芙蓉区乡建设局网站有关建设旅游网站的公司
  • 郑州网站分析免费建博客网站
  • 仪征市建设局网站网站制作中帐号登录怎么做