3 回答
TA贡献1891条经验 获得超3个赞
无论线程如何,对象是否始终看到其最新的内部状态?
为了清楚这个问题及其答案的目的,一个物体不做任何事情;它只是记忆。线程是执行实体。说一个物体能看到什么东西是误导性的。它是执行对象状态的查看/读取的线程。
这在爪哇语中没有指定,但是
Executors.newScheduledThreadPool(5);
返回 .ScheduledThreadPoolExecutor
您的代码正在使用
executorService.scheduleWithFixedDelay(counter, 1, 1, TimeUnit.SECONDS);
调度线程池资源管理器#scheduleded与固定状态
的 javadoc
提交一个周期性操作,该操作在给定的初始延迟之后首先启用,随后在一个执行终止和下一个执行开始之间的给定延迟下启用。
爪哇类进一步澄清
通过或不重叠计划的定期任务的连续执行。虽然不同的执行可能由不同的线程执行,但先前执行的效果发生在后续执行之前。
scheduleAtFixedRate
scheduleWithFixedDelay
因此,保证 每个执行 都可以看到 在上一次执行递增后的值。例如,第三次执行将读取一个值,然后再执行其增量。Counter#run
count
count
2
对于此特定用例,您不需要或任何其他附加的同步机制。volatile
TA贡献1804条经验 获得超8个赞
不,此代码不是线程安全的,因为在以 开始的不同线程中所做的增量之间没有任何发生任何关系。ScheduledExecutorService
要修复此问题,您需要将变量标记为 或切换到 或 。volatile
AtomicInteger
AtomicLong
更新:
@BoristheSpider 如前所述,一般来说,在递增/递减的情况下,做一个变量是不够的,因为递增/递减本身不是原子的,并且同时从多个线程调用它将导致争用条件和错过更新。但是,在这种特殊情况下,保证(根据Javadoc)计划任务的重叠执行,因此即使在增量的情况下,也在此特定情况下也有效。volatile
scheduleWithFixedDelay()
volatile
添加回答
举报