[
https://issues.apache.org/jira/browse/ZOOKEEPER-5052?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Dávid Paksy updated ZOOKEEPER-5052:
-----------------------------------
Description:
We have a classic concurrency problem in JvmPauseMonitor: a non-volatile shared
primitive variable is being updated by one thread, making the new value
invisible to other threads.
Problematic fields:
{noformat}
private long numGcWarnThresholdExceeded = 0;
private long numGcInfoThresholdExceeded = 0;
private long totalGcExtraSleepTime = 0;
{noformat}
We discovered this because JvmPauseMonitorTest has timed out intermittently.
The Problem
In the Java Memory Model, threads use local memory caches for performance. When
a thread updates a primitive (like int, boolean, or double) without proper
synchronization, the change stays in that thread's local cache. Other threads
reading that variable will continue seeing the old, "stale" value, resulting in
race conditions or infinite loops.
The Fix
Add volatile to the three long counters: this ensures all threads read the
latest value directly from main memory.
Using AtomicLong would be an overkill here.
was:
We have a classic concurrency problem in JvmPauseMonitor: a non-volatile shared
primitive variable is being updated by one thread, making the new value
invisible to other threads.
Problematic fields:
{noformat}
private long numGcWarnThresholdExceeded = 0;
private long numGcInfoThresholdExceeded = 0;
private long totalGcExtraSleepTime = 0;
{noformat}
We discovered this because JvmPauseMonitorTest has timed out intermittently.
The Problem
In the Java Memory Model, threads use local memory caches for performance. When
a thread updates a primitive (like int, boolean, or double) without proper
synchronization, the change stays in that thread's local cache. Other threads
reading that variable will continue seeing the old, "stale" value, resulting in
race conditions or infinite loops.
The Fix
Since we so compound operations (incrementing) on these, we shall use Java's
java.util.concurrent.atomic classes.
{noformat}
private final AtomicLong count = new AtomicLong(0);
// To update: count.incrementAndGet();
{noformat}
> Fix stale thread write of primitive in JvmPauseMonitor
> ------------------------------------------------------
>
> Key: ZOOKEEPER-5052
> URL: https://issues.apache.org/jira/browse/ZOOKEEPER-5052
> Project: ZooKeeper
> Issue Type: Bug
> Reporter: Dávid Paksy
> Assignee: Dávid Paksy
> Priority: Major
>
> We have a classic concurrency problem in JvmPauseMonitor: a non-volatile
> shared primitive variable is being updated by one thread, making the new
> value invisible to other threads.
> Problematic fields:
> {noformat}
> private long numGcWarnThresholdExceeded = 0;
> private long numGcInfoThresholdExceeded = 0;
> private long totalGcExtraSleepTime = 0;
> {noformat}
> We discovered this because JvmPauseMonitorTest has timed out intermittently.
> The Problem
> In the Java Memory Model, threads use local memory caches for performance.
> When a thread updates a primitive (like int, boolean, or double) without
> proper synchronization, the change stays in that thread's local cache. Other
> threads reading that variable will continue seeing the old, "stale" value,
> resulting in race conditions or infinite loops.
> The Fix
> Add volatile to the three long counters: this ensures all threads read the
> latest value directly from main memory.
> Using AtomicLong would be an overkill here.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)