纸聊

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 39|回复: 0

五分钟了解竞态条件的危险

[复制链接]

1

主题

0

回帖

7

积分

新手上路

Rank: 1

积分
7
suchonasuchi160 发表于 2024-2-12 12:43:17
本帖最后由 suchonasuchi160 于 2024-2-13 11:54 编辑

目录 竞赛条件 一个简单的例子 增量如何创建竞争条件 一个不那么简单的例子 结论 评论 竞争条件是多线程代码的一个不受欢迎的属性。它表示程序的结果取决于特定的操作顺序,但底层平台(对于 Java,即 JVM)并不保证该顺序。因此,结果通常会在运行过程中波动,因为它取决于不同线程的操作如何准确地交错。在 Java 中,当多个线程共享和改变同一个对象时,最常出现竞争条件。 本文的唯一先决条件是具备线程的基本知识。 竞赛条件 一个简单的例子 让我们从一个例子开始。这里我实现了一个Runnable将共享计数器增加一万次的方法由于标准 Java 的值Integer在创建后无法更新,因此我实现了一个MutableInteger具有两个方法的简单类: increment来增加它的价值 getValue以获得结果值。


这样,我们可以将相同的计数器传递给多个线程,这些线程将并行地递增它如果您不确定如何或join工作,请阅读这篇五分钟的线程介绍。) 由于我们有 10 个线程,每个线程执行 10,000 次增量,因此我们可能期望最 埃及 WhatsApp 号码列表 终值为。但实际结果可能会让你大吃一更令人惊讶的是,每次执行应用程序时总和都不同,但总是小于 增量如何创建竞争条件 为了理解这里发生的情况,我们需要了解增量操作的工作原理。您可能认为这是一个不可分割的操作,并且没有任何中间状态,但实际上,CPU 执行多个低级指令,如下所示 当只有一个线程更新计数器时,这不会导致任何问题。但是,当存在多个线程时,它们可以互相踩踏并以任意顺序执行这些低级操作 在这个特定的示例中,线程 1 和 2 都将相同的内容加载i到5各自的临时变量中。




因此,在增加两个增量之后写6回,但两个增量的期望结果将是7。 这就是为什么当我们运行应用程序时最终结果总是小于 100,000。单个线程不知道还有其他线程也在递增相同的数字。因此,最终结果取决于哪个线程以何种顺序访问内存。 一个不那么简单的例子 当我们使用复杂的数据结构时,竞争条件也可能发生。让我们看一个多个线程更新 a 的同一个实例的示例我们可以再次启动 10 个线程,每个线程应该将 10_000 个元素添加到同一个列表中,并等待它们完成。这是我得作的。在内部LinkedList表示为节点链,每个节点包含两个引用 所有变量都是两个线程的本地变量this.last。它们读取和写入共享字段的顺序决定了程序的成败。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|小黑屋|纸聊

GMT+8, 2024-7-19 07:42 , Processed in 0.052656 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表