为什么在 10 个 Java 线程中递增一个数字不会得到 10 的值?

2024-05-14

我不明白'a'的值为0,为什么'a'不是10,那段代码的运行过程是怎样的,是否需要从Java内存模型来分析?这是我的测试代码

package com.study.concurrent.demo;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

//@SpringBootTest
@Slf4j
class DemoApplicationTests {

    int a = 0;
    int b = 0;
    @Test
    void contextLoads() {
        ExecutorService executorService = Executors.newFixedThreadPool(1);
//        final Semaphore semaphore = new Semaphore(3);
        for (int i = 0; i < 10; i++) {
            executorService.execute(() -> {
//                try {
//                    semaphore.acquire();
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
                add();
                bdd();
//              log.info("a: {},concurrent_id: {}",a,Thread.currentThread().getName());
//                semaphore.release();
            });
        }
        executorService.shutdown();
        log.info("The final value of a:{}",a);
        log.info("The final value of b:{}",b);
    }


    public void add(){
        a++;
    }
    public void bdd(){
        b++;
    }

}


两个原因:

  1. 您不是在等待线程完成,您只是关闭线程池(即:导致线程池拒绝新任务但继续处理现有任务)。

  2. 您没有在线程池中的写入和主线程中的读取之间建立发生之前的关系。

    您可以通过(以及其他方法)执行此操作:

    1. 读取前获取信号量a;
    2. 通过使用submit代替execute得到一个Future<?>对于提交的每个任务,并调用Future.get()所有返回的 future 的方法。它记录在的 JavadocExecutorService https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html这建立了一个发生之前。

第一点是“主要原因”a结果为零:如果我在本地运行它,并等待线程池终止,a结果是 10。

然而,仅仅因为它的结果是 10,并不意味着如果不注意第二点,代码就能正常工作:您需要应用 Java 内存模型来保证正确运行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在 10 个 Java 线程中递增一个数字不会得到 10 的值? 的相关文章

随机推荐

  • 如何在 Android 应用程序中隐藏 Flutterwave API 密钥

    我正在构建一个 Android 应用程序 目前正在将 Flutterwave 集成到我的应用程序中以进行支付 建议我永远不要将 Flutterwave API 密钥放在我的应用程序上 那么我该如何隐藏这些键呢 我正在使用 Retrofit
  • 使用 Node.JS,如何将 JSON 文件读入(服务器)内存?

    背景 我正在使用 Node js 进行一些实验 并且希望从文本文件或 js 文件 哪个更好 读取 JSON 对象到内存中 以便我可以从代码快速访问该对象 我意识到有像 Mongo Alfred 等这样的东西 但这不是我现在需要的 Quest
  • 如何从 m3u 字符串中检索变量=“值”对

    我有 m3u 文件 其中包含类似示例的行 EXTINF 0 ExtFilter Viva group title Variedades tvg logo logo Viva png tvg name Viva 我在 PHP 中运行此命令但没
  • 为神经网络打乱两个 numpy 数组

    我有两个 numpy 数组用于输入数据 X 和输出数据 y X np array 2 3 sample 1 x 16 4 dtype float sample 2 x y np array 1 0 sample 1 y 0 1 dtype
  • 粘表行

    我正在尝试实现一个像 iOS 那样的日历列表视图 基本上 我现在正在做的就是循环遍历我的事件数组 如果是新日期 则打印日期标题 否则打印日历事件 我想让日期标题行保持粘性 直到它们 滚动走 我怎样才能做到这一点 我看到很多关于粘性标题的示例
  • 如何更改文本字段颤动内部的值?

    我有一个TextEditingController如果用户单击按钮 它就会填写信息 我似乎不知道如何更改 a 中的文本Textfield or TextFormField 有解决办法吗 只需更改text财产 TextField contro
  • 元素数组中数组的 MongoDB 全文

    当元素数组中的数组包含应与我的搜索匹配的文本时 我无法检索文档 以下是两个示例文档 id foo name Thing1 data text X X name Thing2 data text X Y id foo
  • 返回一个dispatch_async获取的变量[重复]

    这个问题在这里已经有答案了 基本上 一个方法需要返回一个在dispatch async中获取的NSDictionary 这是我尝试过的 NSDictionary fetchNSDictionary dispatch queue t Queu
  • AWS EC2 应用程序负载均衡器 + 双向 SSL?

    是否可以使用 AWS Application Load Balancer 并使用双向 ssl 客户端证书 我当前的设置使用经典的 ELB 通过 tcp 转发到 Web 服务器端点来支持此操作 我现在需要使用 URL 路由流量 并希望在可能的
  • 在 Matlab 的命令窗口中获取旧式帮助

    问题的简短版本 在最新版本的 Matlab 中 我在 Windows 上的 R2014b 和 R2015a 中看到过 当您键入help foo你得到一个简要描述 简介函数及其签名 例如 输入help bsxfun产生类似这样的东西 只有更好
  • 在 Ubuntu 16.04 上找不到 printf.c

    我最近切换到Ubuntu 16 04 我在用vscode作为 Ubuntu 上的 IDE 我配置了其他语言 但我无法做到这一点C C 我创建c cpp properties json launch json tasks json 当我开始编
  • 为什么在谈论线程和进程时,“不要同时格式化软盘”的评论很有趣?

    我正在阅读之间的区别线程和进程 https stackoverflow com questions 200469 what is the difference between a process and a thread并在第二个答案中发现
  • Java 中的 <-- 是什么? [复制]

    这个问题在这里已经有答案了 我遇到了下面的片段 它输出到4 3 2 1 我从来没有遇到过 lt 在爪哇 Is lt 使 var1 的值变为 var2 的运算符 public class Test public static void mai
  • 安装tensorflow的正确命令

    当尝试在 Anaconda 上安装 Tensorflow 时 我尝试了两种类型的命令 conda install tensorflow gpu工作得很好 然而 当尝试conda install c anaconda tensorflow g
  • PHP ASCII 表库 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有一个事实上的标准库用于在 PHP 中创建 ASCII 表 我想要一些 PHP 代码 当传递数组或其
  • 无法在 Android Studio 中导出签名的 APK

    当我使用keytool list keystore path to keyfile jks并提供我的密码 我可以看到那里的条目 但是当我在尝试使用相同的密码生成签名的 APK 时使用相同的密码时 我收到错误 无法加载密钥库 密钥库被篡改 或
  • Node.js“需要”其他文件而不需要命名空间

    我正在将代码库从 100 浏览器端切换为浏览器端和服务器端的混合 我发现的问题是 要让我的代码使用 node js 运行 我必须使用模块 为了将我的代码变成模块 需要对几乎所有代码进行巨大的重构 原因是在浏览器上 许多功能是跨文件使用的 而
  • Xcode 11 无法识别静态库的架构:MacCatalyst(又名 UIKitForMac)

    在对 2019 年 WWDC 公告感到兴奋之后 我尝试使用 Xcode 11 0 beta 针对 MacOS 编译现有的 iOS 应用程序 不幸的是 事情并没有按预期进行 Xcode 说我的静态库是为 架构构建的 为 Mac 版 UIKit
  • FCM onMessage 无法在 Firefox 中工作,但可以在 chrome 中工作

    我的代码是工作完美在chrome上 版本103 0 5060 134 但是当我在firefox 103 0 上尝试时它不工作 Service Worker 注册成功 但无法接收通知 消息 控制台中没有显示错误 这是我的代码 顺便说一句 我正
  • 为什么在 10 个 Java 线程中递增一个数字不会得到 10 的值?

    我不明白 a 的值为0 为什么 a 不是10 那段代码的运行过程是怎样的 是否需要从Java内存模型来分析 这是我的测试代码 package com study concurrent demo import lombok extern sl