CAS 和 Sychronized的在CPU密集计算情况下的博弈

2024-08-28 05:38

本文主要是介绍CAS 和 Sychronized的在CPU密集计算情况下的博弈,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

很多时候听到使用CAS很优秀。。。

但是CAS是银弹吗?

从实现角度上,sychronized当线程获得不到锁的时候把线程挂起,而CAS不会挂起,而是继续重试。

比如下面的一个场景

i++ 的场景,以下代码是AtomicInteger的i++源码

  public final int getAndIncrement() {return unsafe.getAndAddInt(this, valueOffset, 1);}

底层是用的就是unsafeCAS实现。

public static void main(String[] args) throws InterruptedException {AtomicInteger i = new AtomicInteger();Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {long start = System.currentTimeMillis();for (int j = 0; j < 100000000; j++) {i.incrementAndGet();}long end = System.currentTimeMillis();System.out.println(end - start + " ms");}});t1.start();t1.join();}

测试1亿次计算(粗略计算),458ms,cpu差不过50%左右。(i7-8700)
那么也就是说1ms可以计算2000000(2百万次)


因为我们计算一次的时候,需要调用cas函数一次,
那么两个线程竞争的时候,可以得出线程1(成功了)调用了CAS1次,而线程2调用了CAS两次
其实,我们可以得出一个公式
f(1) = 1,
f(2) = 2- -加上重试失败的一次,
f(2) =3 --加上重试失败的两次,

f(n) = n
那么也就是说如果有200个线程(201核cpu)一致在重试的话,
200! = f(200) + f(199) +…+f(2)+f(1) = 20100次
相当于200个线程同时竞争的情况下,i++成功计算的是0.02ms。
这点时间是微不足道

但是再回想一下区别,synchronized会阻塞线程,或者说是挂起

因为java程序在挂起唤醒线程的时候需要从用户态切换到内核态,这是非常消耗资源的。

那么这个时间消耗是多少呢?

不得而知,相比于0.02ms应该还是大些,或者小一些。

以上的例子举的是运算极快(释放锁极快,成功率高)的场景

但是当存在成功率低的,或者是上面的例子丰富一下,造一个下面的

在这里插入图片描述
这个程序其实应该用long的

我把主线程睡了120s(),还没有算完。但是如果按照我们之前的一个线程一个线程的计算的话,500ms * 200 = 100s也能算完,并且CPU也不会满载。
所以这个时候使用sychronized是不是也很合适呢?

这篇文章主要是表示了我对线程阻塞和不阻塞对时间损耗的一些思考。场景可能有些模糊。欢迎拍砖!!!

注:当然synchronized现在也有自旋锁。

这篇关于CAS 和 Sychronized的在CPU密集计算情况下的博弈的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1113880

相关文章

poj2505(典型博弈)

题意:n = 1,输入一个k,每一次n可以乘以[2,9]中的任何一个数字,两个玩家轮流操作,谁先使得n >= k就胜出 这道题目感觉还不错,自己做了好久都没做出来,然后看了解题才理解的。 解题思路:能进入必败态的状态时必胜态,只能到达胜态的状态为必败态,当n >= K是必败态,[ceil(k/9.0),k-1]是必胜态, [ceil(ceil(k/9.0)/2.0),ceil(k/9.

hdu3389(阶梯博弈变形)

题意:有n个盒子,编号1----n,每个盒子内有一些小球(可以为空),选择一个盒子A,将A中的若干个球移到B中,满足条件B  < A;(A+B)%2=1;(A+B)%3=0 这是阶梯博弈的变形。 先介绍下阶梯博弈: 在一个阶梯有若干层,每层上放着一些小球,两名选手轮流选择一层上的若干(不能为0)小球从上往下移动,最后一次移动的胜出(最终状态小球都在地面上) 如上图所示,小球数目依次为

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <

XTU 1237 计算几何

题面: Magic Triangle Problem Description: Huangriq is a respectful acmer in ACM team of XTU because he brought the best place in regional contest in history of XTU. Huangriq works in a big compa

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

计算数组的斜率,偏移,R2

模拟Excel中的R2的计算。         public bool fnCheckRear_R2(List<double[]> lRear, int iMinRear, int iMaxRear, ref double dR2)         {             bool bResult = true;             int n = 0;             dou

Java程序到CPU上执行 的步骤

相信很多的小伙伴在最初学习编程的时候会容易产生一个疑惑❓,那就是编写的Java代码究竟是怎么一步一步到CPU上去执行的呢?CPU又是如何执行的呢?今天跟随小编的脚步去化解开这个疑惑❓。 在学习这个过程之前,我们需要先讲解一些与本内容相关的知识点 指令 指令是指导CPU运行的命令,主要由操作码+被操作数组成。 其中操作码用来表示要做什么动作,被操作数是本条指令要操作的数据,可能是内存地址,也

如何保证android程序进程不到万不得已的情况下,不会被结束

最近,做一个调用系统自带相机的那么一个功能,遇到的坑,在此记录一下。 设备:红米note4 问题起因 因为自定义的相机,很难满足客户的所有需要,比如:自拍杆的支持,优化方面等等。这些方面自定义的相机都不比系统自带的好,因为有些系统都是商家定制的,难免会出现一个奇葩的问题。比如:你在这款手机上运行,无任何问题,然而你换一款手机后,问题就出现了。 比如:小米的红米系列,你启用系统自带拍照功能后