一个对象是否总是看到其最新的内部状态而与线程无关? [英] Does an object always see its latest internal state irrespective of thread?

查看:61
本文介绍了一个对象是否总是看到其最新的内部状态而与线程无关?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

比方说,我有一个带有简单整数计数变量的可运行对象,该变量在每次可运行对象运行时都会增加.该对象的一个​​实例被提交以在计划的执行程序服务中定期运行.

Let's say I have a runnable with a simple integer count variable which is incremented every time runnable runs. One instance of this object is submitted to run periodically in a scheduled executor service.

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变量时,我们是否有可能丢失对它的更新?

Here, the object is accessing its own internal state inside of different threads (reading and incrementing). Is this code thread-safe or is it possible that we lose updates to the count variable when it's scheduled in a different thread?

推荐答案

对象是否总是看到其最新内部状态而与线程无关?

仅出于本问题及其答案的目的,一个对象什么都不做.这只是记忆.线程是执行实体.说有物体看见任何东西是一种误导.正是线程正在查看/读取对象状态.

Just to be clear for the purposes of this question and its answers, an object doesn't do anything; it's just memory. Threads are the executing entity. It's misleading to say does an object see whatever. It's the thread that's doing the seeing/reading of object state.

这不是在Javadoc中指定的,但是

This isn't specified in the javadoc, but

Executors.newScheduledThreadPool(5);

返回一个ScheduledThreadPoolExecutor.

您的代码正在使用

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

The javadoc for ScheduledThreadPoolExecutor#scheduledWithFixedDelay states

提交一个周期性操作,该操作在给定后首先启用 初始延迟,然后在给定的延迟之间 终止一个执行并开始执行下一个.

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.

通过计划的定期任务的成功执行 scheduleAtFixedRatescheduleWithFixedDelay不重叠. 尽管不同的线程可能执行不同的执行,但是 之前执行的效果发生在后续执行之前.

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的值增加前一次执行后就可以看到.例如,第三次执行将在执行递增操作之前读取count2.

As such, each execution of Counter#run is guaranteed to see the value of count after it's been incremented by the previous execution. For example, the third execution will read a count value of 2 before it performs its increment.

对于此特定用例,您不需要volatile或任何其他其他同步机制.

You don't need volatile or any other additional synchronization mechanism for this specific use case.

这篇关于一个对象是否总是看到其最新的内部状态而与线程无关?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆