首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

JDK 8 新增的 LongAdder,得过来看一下!

数组,当非空时,大小是 2 的幂。...cells:Cell[] cell 数组,当非空时,大小是 2 的幂。 base:long 型,Base 值,在无争用时使用,表初始化竞赛期间的后备。使用 CAS 更新。...获取索引处的 cell , cell 为空则进行初始化。 cell 不为空,使用 cas 更新, 成功 break; 跳出循环, 失败则还在循环内,会一直尝试。...未发生竞争时(Cells 数组未初始化),是对 base 变量进行原子操作。 发生竞争时,每个线程对自己的 Cell 变量的 value 进行原子操作。 如何确定哪个线程操作哪个 cell?...初始化时会创建长度为 2 的 Cell 数组。扩容是创建一个长度是原数组长度 2 倍的新数组,并循环赋值。

37930

Python 自动化指南(繁琐工作自动化)第二版:十三、使用 EXCEL 电子表格

注意,传递的是整数2,而不是字符串'B'。 您可以使用Worksheet对象的max_row和max_column属性来确定工作表的大小。...使用索引或带有关键字参数row和column的cell()工作表方法。 获取一个Cell对象。 读取Cell对象的value属性。...由于代码使用了PRICE_UPDATES字典,而不是将产品名称和更新的成本硬编码到for循环中,所以如果产品销售电子表格需要额外的更改,只需修改PRICE_UPDATES字典,而不用修改代码。...如何在单元格中设置公式? 如果您想要检索单元格公式的结果,而不是单元格公式本身,您必须首先做什么? 如何将第 5 行的高度设置为 100? 你如何隐藏 C 列?...图 13-12:在第 3 行插入前(左)后(右)两个空白行 你可以通过读入电子表格的内容来编写这个程序。然后,当写出新的电子表格时,使用一个for循环来复制前N行。

18.4K53
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    阿里巴巴写进Java开发手册里推荐的JUC工具类:LongAdder,确定不点进来学一下嘛?

    AtomicLong不是多个线程争夺一个value嘛?现在我们在LongAdder中就创建多个临时的value来供线程进行增值操作,而真正的value值等于这些临时value的值求和。...由于缓存行是共享的,当一个线程修改其中一个变量时,整个缓存行的状态会被标记为“脏”(dirty),其他线程必须重新加载整个缓存行,即使它们访问的是缓存行中的其他变量。...a 和 b 是两个独立的变量,但它们可能位于同一个缓存行中。当线程 1 修改 a 时,整个缓存行会被标记为脏,线程 2 也需要重新加载缓存行,尽管它只关心 b。这就是伪共享问题。...这是因为当多个线程同时更新 LongAdder 时,它们可能正在修改 base 值或者 Cell 数组中的值。...由于这些更新操作是并发进行的,所以在调用 sum() 方法时,可能有些更新尚未完成,从而导致返回的总和不是最新的精确值。 在读完这个类之后,其实越来越发现JUC的底层很多类的设计思想是共通的。

    7400

    【小家java】AtomicLong可以抛弃了,请使用LongAdder代替(或使用LongAccumulator)

    当更新方法add(long)在线程间竞争时,该组变量可以动态增长以减缓竞争。方法sum()返回当前在维持总和的变量上的总和。...(这种机制特别像分段锁机制) 与AtomicLong相比,LongAdder更多地用于收集统计数据,而不是细粒度的同步控制。在低并发环境下,两者性能很相似。...就是将value值分离成一个数组,当多线程访问时,通过hash算法映射到其中的一个数字进行计数。而最终的结果,就是这些数组的求和累加。这样一来,就减小了锁的粒度。如下图所示: ?...在实现的代码中,LongAdder一开始并不会直接使用Cell[]存储。而是先使用一个long类型的base存储,当casBase()出现失败时,则会创建Cell[]。...它更多地用于收集统计数据,而不是细粒度的同步控制。 LongAdder只提供了add(long)和decrement()方法,想要使用CAS更全面的方法还是要选择AtomicLong。

    4K50

    (转)比AtomicLong还高效的LongAdder源码解析

    正式开始前,强调下,我们知道,AtomicLong的实现方式是内部有个value 变量,当多线程并发自增,自减时,均通过cas 指令从机器指令级别操作保证并发的原子性。...没错,并发的时候,好戏开始了,AtomicLong的处理方式是死循环尝试更新,直到成功才返回,而LongAdder则是进入这个分支。...计算出一个在Cells 数组中当先线程的HashCode对应的 索引位置,并将该位置的Cell 对象拿出来更新cas 更新它的value值。...给空的cells变量赋一个新的Cell数组。 是不是这样呢?...因此,我想可不可以调换add方法中的判断顺序,比如,先做casBase的判断,结果是 不调换可能更好,调换后每次都要CAS一下,在高并发时,失败几率非常高,并且是恶性循环,比起一次判断,后者的开销明显小很多

    79430

    Python 自动化指南(繁琐工作自动化)第二版:四、列表

    列表数据类型 列表是一个包含有序序列中多个值的值。术语列表值指的是列表本身(它是一个可以存储在变量中或像任何其他值一样传递给函数的值),而不是列表值内部的值。...使用列表的好处是你的数据现在是在一个结构中,所以你的程序在处理数据时比使用几个重复变量要灵活得多。 将for循环用于列表 在第 2 章中,你学习了如何使用for循环来执行一段代码一定的次数。...当您创建列表 ➊ 时,您在spam变量中为它分配一个引用。但是下一行 ➋ 只复制了spam到cheese中的列表引用,而不是列表值本身。这意味着存储在spam和cheese中的值现在都指向同一个列表。...只有一个新的引用被创建并存储在cheese中,而不是一个新的列表。注意这两个引用是如何引用同一个列表的。 图 4-5:spam = cheese复制引用,不是列表。...您不需要担心垃圾收集器是如何工作的,这是一件好事:在其他编程语言中,手动内存管理是常见的错误来源。 引用传递 引用对于理解参数如何传递给函数尤其重要。当调用函数时,实参的值被复制到形参变量中。

    1.5K20

    Go常见错误集锦之range常踩的那些坑

    我们不必处理索引初始化和终止条件。首先,我们先回顾下range的用法;然后我们深入研究range是如何给循环变量赋值的。...我们知道了value是值的拷贝,那接下来我们来看看range 后的表达式是如何被计算的,这个也是Go开发者经常忽略的一个地方。...所以该循环不会无休止的进行下去,而是遍历了3个元素就结束了。 2.2 当range的exp是数组时 当range的exp是数组时 又是怎么样的呢?...然而,这段代码实际上输出的是2,而不是10。我们看下为什么?...总之,当我们使用range循环的时候,我们是将迭代的元素赋值给了一个变量,而该变量只被初始化一次,拥有唯一的内存地址,只不过每次迭代时引用的元素不一样而已。

    71510

    Java原子操作Atomic类详解

    类里面存储的是通用对象,而AtomicStampedReference类则在通用对象上面封装一层(有点类似于修饰器的思维)。             ...,因为调用这个方法时还有其他线程可能正在进行计数累加,方法的返回时刻和调用时刻不是同一个点,在有并发的情况下,这个值只是近似准确的计数值 public long sum() { Cell[] as...由于计算总和时没有对Cell数组进行加锁,所以在累加过程中可能有其他线程对Cell中的值进行了修改,也有可能对数组进行了扩容,所以sum返回的值并不是非常精确的,其返回值并不是一个调用sum方法时的原子快照值...为false,说明上一次循环中找到的下边是没有元素的,那么就自旋一次并rehash,如果再次运行到这里,并且collide为true,就说明明竞争非常激烈,应当扩容了(是不是有点疑惑?...本质上是采用满足条件进入赋值操作来结束这次循环,当第二次到这里的时候才会跳过,走到下面的扩容) else if (!

    72520

    scRNA-seq—读入数据详解

    HMS数据管理工作组深入讨论了数据创建和分析之外需要考虑的一些问题。 数据管理的一个重要方面是组织。对于您进行和分析数据的每个实验,最佳实践是通过创建计划的存储空间(目录结构)来组织。...有关如何执行此操作的具体代码和说明,请参阅其他的材料。 2.Read10X():此功能来自Seurat软件包,并将使用Cell Ranger输出目录作为输入。...读取一个样本(`Read10x()`) 当使用10X数据及其专有软件Cell Ranger时,您将始终拥有outs目录。...当您使用Read10X()函数读入数据时,Seurat会自动为每个细胞创建一些元数据。此信息存储在seurat对象的meta.data槽中(更多内容请参阅下面的注释)。...如果您有15个文件夹作为输入,而不是2个,那么对于每个数据文件夹,上面的代码将运行15次。

    4.3K20

    浅析LongAdder

    当多个线程同时更新(特指“add”)值时,为了减少竞争,可能会动态地增加这组变量的数量。“sum”方法(等效于longValue方法)返回这组变量的“和”值。...当我们的场景是为了统计技术,而不是为了更细粒度的同步控制时,并且是在多线程更新的场景时,LongAdder类比AtomicLong更好用。 在小并发的环境下,论更新的效率,两者都差不多。...[]数组还未初始化 //2.cell[]数组虽然初始化了但是数组长度为0 //3.该线程所对应的cell为null,其中要注意的是,当n为2的n次幂时,(...1 : h; } } //尝试使用casBase对value值进行update,baseOffset是value相对于LongAdder对象初始位置的内存偏移量...答案就在LongAdder的java doc中,从我们翻译的那段可以看出,LongAdder适合的场景是统计求和计数的场景,而且LongAdder基本只提供了add方法,而AtomicLong还具有cas

    48410

    通过构建扫雷游戏来磨练高级 Bash 技能【Programming】

    怀旧经典游戏可能是掌握编程的重要来源。 与扫雷一起深入Bash吧。 image.png 我不是教授编程的专家,但是当我想要在某件事情上做得更好时,我会尝试找到一种方法来享受它。...例如,当我想更好地使用 shell 脚本时,我会决定在 Bash 中编写一个的扫雷游戏。 如果你是一个经验丰富的 Bash 程序员,想要在玩的时候磨练你的技能,那么就跟着在终端中编写你自己的扫雷吧。...另外,我们需要一个数组变量来存储每个单元格的值,我们将使用预定义的全局数组变量 room 和一个索引变量 r。 随着 r 的增加,我们遍历这些单元格,一路上丢下地雷。...通过此数学运算来了解如何计算最终索引“ i ”: i = $ ((( ro * 10 ) + o )) i = $ (((3 * 10 ) + 3)) = $ (( 30 + 3)) = 33 最终索引值为...当提供h6作为输入时,一些值随机填充在我们的雷区中,这些值会在提取分值后添加到用户分数中。

    95600

    Swift基础 字符串和字符

    在每种情况下,都会创建现有String值的新副本,并传递或分配新副本,而不是原始版本。值类型在结构中描述,枚举是值类型。...Swift的默认复制String行为确保当函数或方法向您传递String值时,很明显,无论它来自哪里,您都拥有该确切的String值。您可以放心,除非您自己修改,否则传递的字符串不会被修改。...要访问离给定索引更远的索引,您可以使用index(_:offsetBy:)方法,而不是多次调用这些方法之一。 您可以使用下标语法访问特定String索引的Character。...子字符串 当您从字符串(例如,使用下标或类似prefix(_:)的方法获得子字符串时,结果是Substring的实例,而不是另一个字符串。...相比之下,newString是一个字符串——当它从子字符串创建时,它有自己的存储空间。

    19000

    Python 自动化指南(繁琐工作自动化)第二版:附录 C:练习题的答案

    =````= ==是比较两个值并计算出布尔值的等于运算符,而=是将值存储在变量中的赋值运算符。 条件是在流程控制语句中使用的表达式,其计算结果为布尔值。...第三章 函数减少了对重复代码的需求。这使得程序更短,更容易阅读,更容易更新。 函数中的代码在调用函数时执行,而不是在定义函数时执行。 def语句定义(即创建)一个函数。...当函数返回时,局部作用域被破坏,其中的所有变量都被遗忘。 返回值是函数调用计算得出的值。像任何值一样,返回值可以用作表达式的一部分。...也就是说,只有copy.deepcopy()会复制列表中的任何列表。 第五章 两个花括号:{} {'foo': 42} 存储在字典中的条目是无序的,而列表中的条目是有序的。...=3).value = 'Hello' cell.row和cell.column 它们分别将工作表中最高的列和行的值保存为整数值。

    99120

    LongAdder的源码学习与理解

    volatile long base; //在cells创建或者扩容时,置为1,表示加锁 transient volatile int cellsBusy; cellsBusy作用是当要修改cells...,需要靠预读数据至缓存来提升效率 而缓存以缓存行为单位,每个缓存行对应着一块内存,一般是64byte 缓存的加入会造成数据副本的产生,即同一份数据会缓存在不同核心的缓存行中 CPU要保证数据的一致性...,如果某个CPU核心更改了数据,其他CPU核心对应的整个缓存行必须失效 因为cell是数组形式,在内存中是连续存储的,一个Cell为24个字节(16字节的对象头和8字节的value),因此缓存行可以存下...注解就是用来解决这个问题,它的原理是在适用此注解的对象或字段的前后各增加128字节大小的padding,从而让CPU将对象预读至缓存时占用不同的缓存行,这样就不会造成对方的缓存行失效 有了AtomicLong...Cell里面有一个初始值为0的long型变量,在同等并发量的情况下,争夺单个变量的线程会减少,这是变相减少了争夺共享资源的并发量,另外多个线程在争夺同一个原子变量时候,如果失败不是自选CAS重试而是尝试获取其他原子变量的锁

    23020

    应用|让Excel的目录超级自动化

    然后在一连串的工作表中来回跳转会异常头痛,所以必然想做一个目录索引以方便跳转,就如同Word里的目录索引一样。 那么你有没有为了生成Excel的目录而痛苦?...答案当然是:有。 比如像这样,目录在工作表切换后自动生成。 比如当工作表的位置发生变动后,目录也自动跟随调整位置。 比如添加新的工作表后,目录在对应的位置就自动添加了超链索引。...比如工作表的名字更改后,目录里的名字和超链也自动修改。 比如工作表被删除后,目录也自动删除其对应的索引。 这样的自动化目录是不是看起来就丝滑了不少,富裕的时间至少可以去喝一杯82年的咖啡。...那么是如何实现的呢?...一个是目录工作表后移导致目录混乱,所以要严格控制For循环中i和j的关系,并且保证目录工作表的位置不变: 第二个可能遇到的问题是再次打开Excel后VBA不工作的问题,主要原因是宏被禁止了。

    1.1K30

    NumPy 超详细教程(3):ndarray 的内部机理及高级迭代

    in row:         print(cell) 输出: 1 2 3 4 5 6 上例中,row 的数据类型依然是 numpy.ndarray,而 cell 的数据类型是 numpy.int32...简单来说,当指定 flags=['external_loop'] 时,将返回一维数组而并非单个元素。...具体来说,当 ndarray 的顺序和遍历的顺序一致时,将所有元素组成一个一维数组返回;当 ndarray 的顺序和遍历的顺序不一致时,返回每次遍历的一维数组(这句话特别不好描述,看例子就清楚了)。...,因为我们选择的是列索引(f_index)。...直观的感受看下图: ? 遍历元素的顺序是由 order 参数决定的,而行索引(c_index)和列索引(f_index)不论如何指定,并不会影响元素返回的顺序。

    1.5K20
    领券