gpt4 book ai didi

java - 无论线程如何,对象是否总是看到其最新的内部状态?

转载 作者:搜寻专家 更新时间:2023-10-30 21:03:40 24 4
gpt4 key购买 nike

假设我有一个带有简单整数计数变量的 runnable,该变量在每次 runnable 运行时递增。此对象的一个​​实例被提交以在预定的执行程序服务中定期运行。

class Counter implements Runnable {
private int count = 0;

@Override
public void run() {
count++;
}
}

Counter counter = new Counter();
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);
executorService.scheduleWithFixedDelay(counter, 1, 1, TimeUnit.SECONDS);

在这里,对象正在不同线程(读取和递增)中访问其自身的内部状态。这段代码是线程安全的吗?或者当 count 变量被安排在不同的线程中时,我们是否有可能丢失对它的更新?

最佳答案

无论线程如何,对象是否总能看到其最新的内部状态?

为了明确这个问题及其答案的目的,对象不会任何事情;这只是内存。线程是执行实体。说一个物体能看到任何东西是一种误导。它是执行对象状态的查看/读取的线程。

这在 javadoc 中没有指定,但是

Executors.newScheduledThreadPool(5);

返回一个 ScheduledThreadPoolExecutor

您的代码正在使用

executorService.scheduleWithFixedDelay(counter, 1, 1, TimeUnit.SECONDS);

javadoc for ScheduledThreadPoolExecutor#scheduledWithFixedDelay

Submits a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next.

类(class)javadoc进一步阐明

Successive executions of a periodic task scheduled via scheduleAtFixedRate or scheduleWithFixedDelay do not overlap. While different executions may be performed by different threads, the effects of prior executions happen-before those of subsequent ones.

因此,Counter#run 的每次执行都保证看到 count 的值在上一次执行后递增。例如,第三次执行将在执行递增之前读取 2count 值。

对于这个特定用例,您不需要volatile 或任何其他额外的同步机制。

关于java - 无论线程如何,对象是否总是看到其最新的内部状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55542189/

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