gpt4 book ai didi

java - 为什么增加10个Java线程中的数字不会导致值10?

转载 作者:行者123 更新时间:2023-12-03 11:17:13 26 4
gpt4 key购买 nike

我不明白'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++;
}

}

最佳答案

两个原因:

  • 您无需等待线程完成,而只是关闭线程池(即:导致线程池拒绝新任务,但继续处理现有任务)。
  • 您没有在线程池中的写操作与主线程中的读操作之间建立事前-事前关系。
    您可以通过(在其他方法中)执行此操作:
  • 在读取a之前获取信号量;
  • 通过使用submit而不是execute为提交的每个任务获取Future<?>,并在所有返回的 future 上调用Future.get()方法。在the Javadoc of ExecutorService 中有记载,这建立了一个事前事件。


  • 第一点是 a出现为零的“主要”原因:如果我在本地运行它,并等待线程池终止,则 a出现为10。
    但是,仅仅因为它出现10并不意味着代码可以正确工作而无需注意第二点:您需要应用Java内存模型来保证正确的功能。

    关于java - 为什么增加10个Java线程中的数字不会导致值10?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66105755/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com