前面的偏向锁,轻量级锁,重量级锁都是悲观锁,

都会认为必须要对操作对象进行互斥访问,不然就会产生异常, 所以线程只供一个线程使用,阻塞其他线程,是悲观的

在某些情况下,同步的耗时远大于线程切换的时间,互斥就有点多余了

所以使用CAS compare ans swap

一个资源 对应一个 tig 为1表示被占用,0表示未被占用

两个线程(称为AB) 均想获取该资源,即都希望当前tig为0 并由自己将其置为1

用代码表示: 逻辑就是这样的

int cas(long* address,long oldValue,long newValue)
{
if(*address!=oldValue){
return 0;
}
*address = newValue;
return 1; }

如果csa失败 则等待。

如果只看代码 同样也是无法实现互斥的,代在底层,我们的CAS 是原子性 的。比较和交换两个操作是一体的。

还有就是底层的循环等待一般也不是死循环,是有限制的

Java中的使用示例:

不使用CAS:

public class Main {

    public static void main(String[] args) {

        int i;
for (i = 0; i < 4; i++) {
new casTest().start();
}
}
} class casTest extends Thread{
public static int a = 0; @Override
public void run() {
while(a<1000){
System.out.println(getName() + " "+a++);
try {
sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

输出:

Thread-0   993
Thread-2 994
Thread-1 995
Thread-3 996
Thread-0 997
Thread-1 998----
Thread-2 998----
Thread-0 999
Thread-3 999

只截了最后几行

可以看到 标记处 两个线程输出了同样的数

代码线程不安全

下面我们尝试使用互斥锁

public class Main {

    public static void main(String[] args) {

        int i;
for (i = 0; i < 4; i++) {
new casTest().start();
} }
} class casTest extends Thread{
public static int a = 0; @Override
public void run() {
while(a<1000){
System.out.println(getName() + " "+a++);
synchronized (Math.class){
a++;
} } }
}

输出:

Thread-2   982
Thread-2 984
Thread-2 986
Thread-2 988
Thread-2 990
Thread-2 992
Thread-2 994
Thread-2 996
Thread-2 998
Thread-1 502
Thread-0 586

无重复

下面我们用 CAS:

import java.util.concurrent.atomic.AtomicInteger;

public class Main {

    public static void main(String[] args) {

        int i;
for (i = 0; i < 4; i++) {
new casTest().start();
} }
} class casTest extends Thread{
// public static int a = 0;
public static AtomicInteger integer = new AtomicInteger(0); @Override
public void run() {
while(integer.get()<1000){
System.out.println(getName() + " "+integer.incrementAndGet()); } }
}

输出:

Thread-1   993
Thread-1 994
Thread-1 995
Thread-1 996
Thread-1 997
Thread-0 960
Thread-0 999
Thread-0 1000
Thread-2 943
Thread-1 998

顺序不同是因为输出的缘故

但不会出现重复,即实现了互斥

下面点进去看看源码:

确实用的是CAS

再往下一点:

这里是native方法

不同系统的代码可能不同,都是基于本地硬件进行CAS操作 c++实现

找到了一个源码的截图:

框框处调用了汇编命令

最新文章

  1. BZOJ 2160: 拉拉队排练
  2. Android 判断字符串是否为空
  3. SaveData Functions
  4. Cocos2d-x数据存储
  5. NOR Flash擦写和原理分析 (二)
  6. Java中获取完整的url
  7. MySQL优化器cost计算
  8. glsl-UBO
  9. Lucene之删除索引
  10. Tomcat禁止外网访问
  11. js继承之原型链方式实现
  12. Babel 入门指南
  13. SpringBoot的几个使用技巧
  14. iOS开发之UIWebView的常见一些用法
  15. golang 结构体中的匿名接口
  16. FFmpeg Scaler Options
  17. 【POJ1456】Supermarket(贪心)
  18. ECMAScript 6 -- 数组的解构赋值
  19. List遍历三种方法:1.for 2.增强性for 3.迭代器
  20. MYSQL如何解决幻读

热门文章

  1. 第2-3-2章 环境搭建-文件存储服务系统-nginx/fastDFS/minio/阿里云oss/七牛云oss
  2. Nginx如何配置隐藏index.php文件
  3. Ubuntu 20.04 开启root权限登陆、网卡配置
  4. Pycharm2022.1.3安装教程(包含基础使用配置)
  5. python编程学习方法及计算机基础理论
  6. 关于linux mint更改资源管理器的快捷键
  7. 07#Web 实战:实现 GitHub 个人主页项目拖拽排序
  8. day10 集合——队列(Queue)、Vector &amp; Map集合常用方法 &amp; HashMap的实现原理&amp;二叉树&amp;二叉查找树AVL树&amp;红黑树
  9. Linux相关命令及软件安装教程
  10. 【每日一题】【双指针、位运算】2022年2月3日-NC103 反转字符串