You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2025/05/03 19:54:58 UTC
(commons-pool) 01/02: Operation on the "idleHighWaterMark" shared variable in "ErodingFactor" class is not atomic [org.apache.commons.pool2.PoolUtils$ErodingFactor] At PoolUtils.java:[line 98] AT_NONATOMIC_OPERATIONS_ON_SHARED_VARIABLE
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch POOL_2_X
in repository https://gitbox.apache.org/repos/asf/commons-pool.git
commit 21eaa240d6f05999b78e1c41586bfed48e98d68b
Author: Gary D. Gregory <ga...@gmail.com>
AuthorDate: Sat May 3 09:16:50 2025 -0400
Operation on the "idleHighWaterMark" shared variable in "ErodingFactor"
class is not atomic [org.apache.commons.pool2.PoolUtils$ErodingFactor]
At PoolUtils.java:[line 98] AT_NONATOMIC_OPERATIONS_ON_SHARED_VARIABLE
---
src/changes/changes.xml | 1 +
.../java/org/apache/commons/pool2/PoolUtils.java | 24 ++++++++++++++--------
2 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 45f56d1b..d56cd543 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -53,6 +53,7 @@ The <action> type attribute can be add,update,fix,remove.
Recompute the remaining duration an additional time when we block when exhausted.
</action>
<action type="fix" dev="ggregory" due-to="Wei Guo, Gary Gregory">Fix site link from the About page to the Download page, see also #387.</action>
+ <action type="fix" dev="ggregory" due-to="Gary Gregory">Operation on the "idleHighWaterMark" shared variable in "ErodingFactor" class is not atomic [org.apache.commons.pool2.PoolUtils$ErodingFactor] At PoolUtils.java:[line 98] AT_NONATOMIC_OPERATIONS_ON_SHARED_VARIABLE.</action>
<!-- ADD -->
<!-- UPDATE -->
<action type="update" dev="ggregory" due-to="Gary Gregory">Bump org.apache.commons:commons-parent from 79 to 81.</action>
diff --git a/src/main/java/org/apache/commons/pool2/PoolUtils.java b/src/main/java/org/apache/commons/pool2/PoolUtils.java
index a6b8b3b5..313cf54b 100644
--- a/src/main/java/org/apache/commons/pool2/PoolUtils.java
+++ b/src/main/java/org/apache/commons/pool2/PoolUtils.java
@@ -23,6 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
+import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
@@ -46,6 +47,9 @@ public final class PoolUtils {
* frequently.
*/
private static final class ErodingFactor {
+
+ private static final float MAX_INTERVAL = 15f;
+
/** Determines frequency of "erosion" events */
private final float factor;
@@ -53,7 +57,9 @@ public final class PoolUtils {
private transient volatile long nextShrinkMillis;
/** High water mark - largest numIdle encountered */
- private transient volatile int idleHighWaterMark;
+ private transient volatile int idleHighWaterMark = 1;
+
+ private final ReentrantLock lock = new ReentrantLock();
/**
* Creates a new ErodingFactor with the given erosion factor.
@@ -63,8 +69,7 @@ public final class PoolUtils {
*/
private ErodingFactor(final float factor) {
this.factor = factor;
- nextShrinkMillis = System.currentTimeMillis() + (long) (900000 * factor); // now + 15 min * factor
- idleHighWaterMark = 1;
+ nextShrinkMillis = System.currentTimeMillis() + (long) (90_0000 * factor); // now + 15 min * factor
}
/**
@@ -95,11 +100,14 @@ public final class PoolUtils {
*/
public void update(final long nowMillis, final int numIdle) {
final int idle = Math.max(0, numIdle);
- idleHighWaterMark = Math.max(idle, idleHighWaterMark);
- final float maxInterval = 15f;
- final float minutes = maxInterval +
- (1f - maxInterval) / idleHighWaterMark * idle;
- nextShrinkMillis = nowMillis + (long) (minutes * 60000f * factor);
+ lock.lock();
+ try {
+ idleHighWaterMark = Math.max(idle, idleHighWaterMark);
+ final float minutes = MAX_INTERVAL + (1f - MAX_INTERVAL) / idleHighWaterMark * idle;
+ nextShrinkMillis = nowMillis + (long) (minutes * 60000f * factor);
+ } finally {
+ lock.unlock();
+ }
}
}
/**