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 2021/02/15 22:15:36 UTC
[commons-pool] 04/06: Add and use java.time.Duration APIs timeouts
instead of using ints for seconds.
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-pool.git
commit 11af26e207f6f759ee368306499f456992c34adf
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Mon Feb 15 16:56:19 2021 -0500
Add and use java.time.Duration APIs timeouts instead of using ints for
seconds.
---
src/changes/changes.xml | 8 +-
.../apache/commons/pool2/impl/AbandonedConfig.java | 2 +-
.../commons/pool2/impl/BaseGenericObjectPool.java | 202 ++-
.../commons/pool2/impl/BaseObjectPoolConfig.java | 169 +-
.../commons/pool2/impl/LinkedBlockingDeque.java | 1677 +++++++++++---------
.../apache/commons/pool2/impl/PoolImplUtils.java | 47 +-
.../apache/commons/pool2/ObjectPoolIssue326.java | 7 +-
.../java/org/apache/commons/pool2/PoolTest.java | 6 +
.../pool2/impl/TestAbandonedObjectPool.java | 19 +-
.../pool2/impl/TestBaseGenericObjectPool.java | 9 +-
.../apache/commons/pool2/impl/TestConstants.java | 1 +
.../pool2/impl/TestGenericKeyedObjectPool.java | 94 +-
.../commons/pool2/impl/TestGenericObjectPool.java | 123 +-
.../impl/TestGenericObjectPoolClassLoaders.java | 5 +-
.../TestGenericObjectPoolFactoryCreateFailure.java | 7 +-
.../pool2/impl/TestLinkedBlockingDeque.java | 30 +-
16 files changed, 1444 insertions(+), 962 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index ab72916..d81cb69 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -45,11 +45,9 @@ The <action> type attribute can be add,update,fix,remove.
<body>
<release version="2.10.0" date="202Y-MM-DD" description="This is a MMMM release (Java 8).">
<!-- ADD -->
- <action dev="ggregory" type="update" due-to="Dependabot">
- Add and use java.time.Duration APIs for AbandonedConfig timeouts instead of using ints for seconds.
- - Add AbandonedConfig.getRemoveAbandonedTimeoutDuration().
- - Add AbandonedConfig.setRemoveAbandonedTimeout(Duration).
- - Add GenericObjectPool.getRemoveAbandonedTimeoutDuration().
+ <action dev="ggregory" type="add" due-to="Dependabot">
+ Add and use java.time.Duration APIs timeouts instead of using ints for seconds.
+ See the site and its API comparison report for a list of the new Duration-based APIs.
</action>
<!-- UPDATE -->
<action dev="ggregory" type="update" due-to="Dependabot">
diff --git a/src/main/java/org/apache/commons/pool2/impl/AbandonedConfig.java b/src/main/java/org/apache/commons/pool2/impl/AbandonedConfig.java
index 0f0b94e..0d94c7d 100644
--- a/src/main/java/org/apache/commons/pool2/impl/AbandonedConfig.java
+++ b/src/main/java/org/apache/commons/pool2/impl/AbandonedConfig.java
@@ -131,7 +131,7 @@ public class AbandonedConfig {
* <p>If set to true, abandoned objects are removed by the pool
* maintenance thread when it runs. This setting has no effect
* unless maintenance is enabled by setting
- *{@link GenericObjectPool#getTimeBetweenEvictionRunsMillis() timeBetweenEvictionRunsMillis}
+ *{@link GenericObjectPool#getTimeBetweenEvictionRuns() timeBetweenEvictionRuns}
* to a positive number.</p>
*
* @return true if abandoned objects are to be removed by the evictor
diff --git a/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java b/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
index f4bcb2c..a642426 100644
--- a/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
+++ b/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
@@ -146,7 +146,7 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
/**
- * Returns the maximum number of objects that can be allocated by the pool
+ * Gets the maximum number of objects that can be allocated by the pool
* (checked out to clients, or idle awaiting checkout) at a given time. When
* negative, there is no limit to the number of objects that can be
* managed by the pool at one time.
@@ -218,9 +218,9 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
setTestOnReturn(config.getTestOnReturn());
setTestWhileIdle(config.getTestWhileIdle());
setNumTestsPerEvictionRun(config.getNumTestsPerEvictionRun());
- setMinEvictableIdleTimeMillis(config.getMinEvictableIdleTimeMillis());
- setTimeBetweenEvictionRunsMillis(config.getTimeBetweenEvictionRunsMillis());
- setSoftMinEvictableIdleTimeMillis(config.getSoftMinEvictableIdleTimeMillis());
+ setMinEvictableIdleTime(config.getMinEvictableIdleTime());
+ setTimeBetweenEvictionRuns(config.getTimeBetweenEvictionRuns());
+ setSoftMinEvictableIdleTime(config.getSoftMinEvictableIdleTime());
final EvictionPolicy<T> policy = config.getEvictionPolicy();
if (policy == null) {
// Use the class name (pre-2.6.0 compatible)
@@ -229,11 +229,11 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
// Otherwise, use the class (2.6.0 feature)
setEvictionPolicy(policy);
}
- setEvictorShutdownTimeoutMillis(config.getEvictorShutdownTimeoutMillis());
+ setEvictorShutdownTimeout(config.getEvictorShutdownTimeout());
}
/**
- * Returns the maximum amount of time (in milliseconds) the
+ * Gets the maximum amount of time (in milliseconds) the
* {@code borrowObject()} method should block before throwing an
* exception when the pool is exhausted and
* {@link #getBlockWhenExhausted} is true. When less than 0, the
@@ -418,7 +418,7 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
/**
* Returns whether objects sitting idle in the pool will be validated by the
* idle object evictor (if any - see
- * {@link #setTimeBetweenEvictionRunsMillis(long)}). Validation is performed
+ * {@link #setTimeBetweenEvictionRuns(Duration)}). Validation is performed
* by the {@code validateObject()} method of the factory associated
* with the pool. If the object fails to validate, it will be removed from
* the pool and destroyed.
@@ -435,7 +435,7 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
/**
* Returns whether objects sitting idle in the pool will be validated by the
* idle object evictor (if any - see
- * {@link #setTimeBetweenEvictionRunsMillis(long)}). Validation is performed
+ * {@link #setTimeBetweenEvictionRuns(Duration)}). Validation is performed
* by the {@code validateObject()} method of the factory associated
* with the pool. If the object fails to validate, it will be removed from
* the pool and destroyed. Note that setting this property has no effect
@@ -446,21 +446,37 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
* {@code true} so objects will be validated by the evictor
*
* @see #getTestWhileIdle
- * @see #setTimeBetweenEvictionRunsMillis
+ * @see #setTimeBetweenEvictionRuns
*/
public final void setTestWhileIdle(final boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
/**
- * Returns the number of milliseconds to sleep between runs of the idle
+ * Gets the duration to sleep between runs of the idle
+ * object evictor thread. When non-positive, no idle object evictor thread
+ * will be run.
+ *
+ * @return number of milliseconds to sleep between evictor runs
+ *
+ * @see #setTimeBetweenEvictionRuns
+ * @since 2.10.0
+ */
+ public final Duration getTimeBetweenEvictionRuns() {
+ return timeBetweenEvictionRuns;
+ }
+
+ /**
+ * Gets the number of milliseconds to sleep between runs of the idle
* object evictor thread. When non-positive, no idle object evictor thread
* will be run.
*
* @return number of milliseconds to sleep between evictor runs
*
* @see #setTimeBetweenEvictionRunsMillis
+ * @deprecated Use {@link #getTimeBetweenEvictionRuns()}.
*/
+ @Deprecated
public final long getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRuns.toMillis();
}
@@ -472,19 +488,38 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
* <li>When non-positive, no idle object evictor thread runs.</li>
* </ul>
*
+ * @param timeBetweenEvictionRuns
+ * duration to sleep between evictor runs
+ *
+ * @see #getTimeBetweenEvictionRunsMillis
+ * @since 2.10.0
+ */
+ public final void setTimeBetweenEvictionRuns(final Duration timeBetweenEvictionRuns) {
+ this.timeBetweenEvictionRuns = timeBetweenEvictionRuns;
+ startEvictor(this.timeBetweenEvictionRuns);
+ }
+
+ /**
+ * Sets the number of milliseconds to sleep between runs of the idle object evictor thread.
+ * <ul>
+ * <li>When positive, the idle object evictor thread starts.</li>
+ * <li>When non-positive, no idle object evictor thread runs.</li>
+ * </ul>
+ *
* @param timeBetweenEvictionRunsMillis
* number of milliseconds to sleep between evictor runs
*
* @see #getTimeBetweenEvictionRunsMillis
+ * @deprecated Use {@link #setTimeBetweenEvictionRuns(Duration)}.
*/
- public final void setTimeBetweenEvictionRunsMillis(
- final long timeBetweenEvictionRunsMillis) {
+ @Deprecated
+ public final void setTimeBetweenEvictionRunsMillis(final long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRuns = Duration.ofMillis(timeBetweenEvictionRunsMillis);
startEvictor(timeBetweenEvictionRuns);
}
/**
- * Returns the maximum number of objects to examine during each run (if any)
+ * Gets the maximum number of objects to examine during each run (if any)
* of the idle object evictor thread. When positive, the number of tests
* performed for a run will be the minimum of the configured value and the
* number of idle instances in the pool. When negative, the number of tests
@@ -523,7 +558,24 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
}
/**
- * Returns the minimum amount of time an object may sit idle in the pool
+ * Gets the minimum amount of time an object may sit idle in the pool
+ * before it is eligible for eviction by the idle object evictor (if any -
+ * see {@link #setTimeBetweenEvictionRuns(Duration)}). When non-positive,
+ * no objects will be evicted from the pool due to idle time alone.
+ *
+ * @return minimum amount of time an object may sit idle in the pool before
+ * it is eligible for eviction
+ *
+ * @see #setMinEvictableIdleTimeMillis
+ * @see #setTimeBetweenEvictionRunsMillis
+ * @since 2.10.0
+ */
+ public final Duration getMinEvictableIdleTime() {
+ return minEvictableIdleTime;
+ }
+
+ /**
+ * Gets the minimum amount of time an object may sit idle in the pool
* before it is eligible for eviction by the idle object evictor (if any -
* see {@link #setTimeBetweenEvictionRunsMillis(long)}). When non-positive,
* no objects will be evicted from the pool due to idle time alone.
@@ -533,7 +585,9 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
*
* @see #setMinEvictableIdleTimeMillis
* @see #setTimeBetweenEvictionRunsMillis
+ * @deprecated Use {@link #getMinEvictableIdleTime()}.
*/
+ @Deprecated
public final long getMinEvictableIdleTimeMillis() {
return minEvictableIdleTime.toMillis();
}
@@ -541,6 +595,24 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
/**
* Sets the minimum amount of time an object may sit idle in the pool
* before it is eligible for eviction by the idle object evictor (if any -
+ * see {@link #setTimeBetweenEvictionRuns(Duration)}). When non-positive,
+ * no objects will be evicted from the pool due to idle time alone.
+ *
+ * @param minEvictableIdleTimeMillis
+ * minimum amount of time an object may sit idle in the pool
+ * before it is eligible for eviction
+ *
+ * @see #getMinEvictableIdleTime
+ * @see #setTimeBetweenEvictionRuns
+ * @since 2.10.0
+ */
+ public final void setMinEvictableIdleTime(final Duration minEvictableIdleTimeMillis) {
+ this.minEvictableIdleTime = minEvictableIdleTimeMillis;
+ }
+
+ /**
+ * Sets the minimum amount of time an object may sit idle in the pool
+ * before it is eligible for eviction by the idle object evictor (if any -
* see {@link #setTimeBetweenEvictionRunsMillis(long)}). When non-positive,
* no objects will be evicted from the pool due to idle time alone.
*
@@ -550,14 +622,35 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
*
* @see #getMinEvictableIdleTimeMillis
* @see #setTimeBetweenEvictionRunsMillis
+ * @deprecated Use {@link #setMinEvictableIdleTime(Duration)}.
*/
- public final void setMinEvictableIdleTimeMillis(
- final long minEvictableIdleTimeMillis) {
+ @Deprecated
+ public final void setMinEvictableIdleTimeMillis(final long minEvictableIdleTimeMillis) {
this.minEvictableIdleTime = Duration.ofMillis(minEvictableIdleTimeMillis);
}
/**
- * Returns the minimum amount of time an object may sit idle in the pool
+ * Gets the minimum amount of time an object may sit idle in the pool
+ * before it is eligible for eviction by the idle object evictor (if any -
+ * see {@link #setTimeBetweenEvictionRuns(Duration)}),
+ * with the extra condition that at least {@code minIdle} object
+ * instances remain in the pool. This setting is overridden by
+ * {@link #getMinEvictableIdleTime} (that is, if
+ * {@link #getMinEvictableIdleTime} is positive, then
+ * {@link #getSoftMinEvictableIdleTime} is ignored).
+ *
+ * @return minimum amount of time an object may sit idle in the pool before
+ * it is eligible for eviction if minIdle instances are available
+ *
+ * @see #setSoftMinEvictableIdleTime(Duration)
+ * @since 2.10.0
+ */
+ public final Duration getSoftMinEvictableIdleTime() {
+ return softMinEvictableIdleTime;
+ }
+
+ /**
+ * Gets the minimum amount of time an object may sit idle in the pool
* before it is eligible for eviction by the idle object evictor (if any -
* see {@link #setTimeBetweenEvictionRunsMillis(long)}),
* with the extra condition that at least {@code minIdle} object
@@ -570,7 +663,9 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
* it is eligible for eviction if minIdle instances are available
*
* @see #setSoftMinEvictableIdleTimeMillis
+ * @deprecated Use {@link #getSoftMinEvictableIdleTime()}.
*/
+ @Deprecated
public final long getSoftMinEvictableIdleTimeMillis() {
return softMinEvictableIdleTime.toMillis();
}
@@ -578,6 +673,28 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
/**
* Sets the minimum amount of time an object may sit idle in the pool
* before it is eligible for eviction by the idle object evictor (if any -
+ * see {@link #setTimeBetweenEvictionRuns(Duration)}),
+ * with the extra condition that at least {@code minIdle} object
+ * instances remain in the pool. This setting is overridden by
+ * {@link #getMinEvictableIdleTime} (that is, if
+ * {@link #getMinEvictableIdleTime} is positive, then
+ * {@link #getSoftMinEvictableIdleTime} is ignored).
+ *
+ * @param softMinEvictableIdleTime
+ * minimum amount of time an object may sit idle in the pool
+ * before it is eligible for eviction if minIdle instances are
+ * available
+ *
+ * @see #getSoftMinEvictableIdleTimeMillis
+ * @since 2.10.0
+ */
+ public final void setSoftMinEvictableIdleTime(final Duration softMinEvictableIdleTime) {
+ this.softMinEvictableIdleTime = softMinEvictableIdleTime;
+ }
+
+ /**
+ * Sets the minimum amount of time an object may sit idle in the pool
+ * before it is eligible for eviction by the idle object evictor (if any -
* see {@link #setTimeBetweenEvictionRunsMillis(long)}),
* with the extra condition that at least {@code minIdle} object
* instances remain in the pool. This setting is overridden by
@@ -591,14 +708,15 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
* available
*
* @see #getSoftMinEvictableIdleTimeMillis
+ * @deprecated Use {@link #setSoftMinEvictableIdleTime(Duration)}.
*/
- public final void setSoftMinEvictableIdleTimeMillis(
- final long softMinEvictableIdleTimeMillis) {
+ @Deprecated
+ public final void setSoftMinEvictableIdleTimeMillis(final long softMinEvictableIdleTimeMillis) {
this.softMinEvictableIdleTime = Duration.ofMillis(softMinEvictableIdleTimeMillis);
}
/**
- * Returns the name of the {@link EvictionPolicy} implementation that is
+ * Gets the name of the {@link EvictionPolicy} implementation that is
* used by this pool.
*
* @return The fully qualified class name of the {@link EvictionPolicy}
@@ -692,22 +810,48 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
*
* @return The timeout in milliseconds that will be used while waiting for
* the Evictor to shut down.
+ * @deprecated Use {@link #getEvictorShutdownTimeout()}.
*/
+ @Deprecated
public final long getEvictorShutdownTimeoutMillis() {
return evictorShutdownTimeout.toMillis();
}
/**
- * Sets the timeout that will be used when waiting for the Evictor to
+ * Gets the timeout that will be used when waiting for the Evictor to
* shutdown if this pool is closed and it is the only pool still using the
* the value for the Evictor.
*
- * @param evictorShutdownTimeoutMillis the timeout in milliseconds that
- * will be used while waiting for the
- * Evictor to shut down.
+ * @return The timeout that will be used while waiting for
+ * the Evictor to shut down.
+ * @since 2.10.0
+ */
+ public final Duration getEvictorShutdownTimeout() {
+ return evictorShutdownTimeout;
+ }
+
+ /**
+ * Sets the timeout that will be used when waiting for the Evictor to shutdown if this pool is closed and it is the
+ * only pool still using the the value for the Evictor.
+ *
+ * @param evictorShutdownTimeoutMillis the timeout in milliseconds that will be used while waiting for the Evictor
+ * to shut down.
+ * @since 2.10.0
+ */
+ public final void setEvictorShutdownTimeout(final Duration evictorShutdownTimeoutMillis) {
+ this.evictorShutdownTimeout = evictorShutdownTimeoutMillis;
+ }
+
+ /**
+ * Sets the timeout that will be used when waiting for the Evictor to shutdown if this pool is closed and it is the
+ * only pool still using the the value for the Evictor.
+ *
+ * @param evictorShutdownTimeoutMillis the timeout in milliseconds that will be used while waiting for the Evictor
+ * to shut down.
+ * @deprecated Use {@link #setEvictorShutdownTimeout(Duration)}.
*/
- public final void setEvictorShutdownTimeoutMillis(
- final long evictorShutdownTimeoutMillis) {
+ @Deprecated
+ public final void setEvictorShutdownTimeoutMillis(final long evictorShutdownTimeoutMillis) {
this.evictorShutdownTimeout = Duration.ofMillis(evictorShutdownTimeoutMillis);
}
@@ -738,7 +882,7 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
public abstract void evict() throws Exception;
/**
- * Returns the {@link EvictionPolicy} defined for this pool.
+ * Gets the {@link EvictionPolicy} defined for this pool.
*
* @return the eviction policy
* @since 2.4
@@ -1223,7 +1367,7 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
}
/**
- * Returns the mean of the cached values.
+ * Gets the mean of the cached values.
*
* @return the mean of the cache, truncated to long
*/
@@ -1278,7 +1422,7 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
}
/**
- * Returns the idle object deque referenced by this iterator.
+ * Gets the idle object deque referenced by this iterator.
* @return the idle object deque
*/
public Deque<PooledObject<T>> getIdleObjects() {
diff --git a/src/main/java/org/apache/commons/pool2/impl/BaseObjectPoolConfig.java b/src/main/java/org/apache/commons/pool2/impl/BaseObjectPoolConfig.java
index 525aede..9147725 100644
--- a/src/main/java/org/apache/commons/pool2/impl/BaseObjectPoolConfig.java
+++ b/src/main/java/org/apache/commons/pool2/impl/BaseObjectPoolConfig.java
@@ -67,7 +67,9 @@ public abstract class BaseObjectPoolConfig<T> extends BaseObject implements Clon
* configuration attribute.
* @see GenericObjectPool#getMinEvictableIdleTimeMillis()
* @see GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()
+ * @deprecated Use {@link #DEFAULT_MIN_EVICTABLE_IDLE_TIME}.
*/
+ @Deprecated
public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS =
1000L * 60L * 30L;
@@ -86,14 +88,16 @@ public abstract class BaseObjectPoolConfig<T> extends BaseObject implements Clon
* configuration attribute.
* @see GenericObjectPool#getSoftMinEvictableIdleTimeMillis()
* @see GenericKeyedObjectPool#getSoftMinEvictableIdleTimeMillis()
+ * @deprecated Use {@link #DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME}.
*/
+ @Deprecated
public static final long DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS = -1;
/**
* The default value for the {@code softMinEvictableIdleTime}
* configuration attribute.
- * @see GenericObjectPool#getSoftMinEvictableIdleTimeMillis()
- * @see GenericKeyedObjectPool#getSoftMinEvictableIdleTimeMillis()
+ * @see GenericObjectPool#getSoftMinEvictableIdleTime()
+ * @see GenericKeyedObjectPool#getSoftMinEvictableIdleTime()
* @since 2.10.0
*/
public static final Duration DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME =
@@ -104,15 +108,16 @@ public abstract class BaseObjectPoolConfig<T> extends BaseObject implements Clon
* attribute.
* @see GenericObjectPool#getEvictorShutdownTimeoutMillis()
* @see GenericKeyedObjectPool#getEvictorShutdownTimeoutMillis()
+ * @deprecated Use {@link #DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT}.
*/
- public static final long DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS =
- 10L * 1000L;
+ @Deprecated
+ public static final long DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS = 10L * 1000L;
/**
* The default value for {@code evictorShutdownTimeout} configuration
* attribute.
- * @see GenericObjectPool#getEvictorShutdownTimeoutMillis()
- * @see GenericKeyedObjectPool#getEvictorShutdownTimeoutMillis()
+ * @see GenericObjectPool#getEvictorShutdownTimeout()
+ * @see GenericKeyedObjectPool#getEvictorShutdownTimeout()
* @since 2.10.0
*/
public static final Duration DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT =
@@ -161,7 +166,9 @@ public abstract class BaseObjectPoolConfig<T> extends BaseObject implements Clon
* configuration attribute.
* @see GenericObjectPool#getTimeBetweenEvictionRunsMillis()
* @see GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()
+ * @deprecated Use {@link #DEFAULT_TIME_BETWEEN_EVICTION_RUNS}.
*/
+ @Deprecated
public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
/**
@@ -341,9 +348,26 @@ public abstract class BaseObjectPoolConfig<T> extends BaseObject implements Clon
* @return The current setting of {@code minEvictableIdleTime} for
* this configuration instance
*
+ * @see GenericObjectPool#getMinEvictableIdleTime()
+ * @see GenericKeyedObjectPool#getMinEvictableIdleTime()
+ * @since 2.10.0
+ */
+ public Duration getMinEvictableIdleTime() {
+ return minEvictableIdleTime;
+ }
+
+ /**
+ * Gets the value for the {@code minEvictableIdleTime} configuration
+ * attribute for pools created with this configuration instance.
+ *
+ * @return The current setting of {@code minEvictableIdleTime} for
+ * this configuration instance
+ *
* @see GenericObjectPool#getMinEvictableIdleTimeMillis()
* @see GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()
+ * @deprecated Use {@link #getMinEvictableIdleTime()}.
*/
+ @Deprecated
public long getMinEvictableIdleTimeMillis() {
return minEvictableIdleTime.toMillis();
}
@@ -352,12 +376,29 @@ public abstract class BaseObjectPoolConfig<T> extends BaseObject implements Clon
* Sets the value for the {@code minEvictableIdleTime} configuration
* attribute for pools created with this configuration instance.
*
+ * @param minEvictableIdleTime The new setting of
+ * {@code minEvictableIdleTime} for this configuration instance
+ *
+ * @see GenericObjectPool#getMinEvictableIdleTime()
+ * @see GenericKeyedObjectPool#getMinEvictableIdleTime()
+ * @since 2.10.0
+ */
+ public void setMinEvictableIdleTime(final Duration minEvictableIdleTime) {
+ this.minEvictableIdleTime = minEvictableIdleTime;
+ }
+
+ /**
+ * Sets the value for the {@code minEvictableIdleTime} configuration
+ * attribute for pools created with this configuration instance.
+ *
* @param minEvictableIdleTimeMillis The new setting of
* {@code minEvictableIdleTime} for this configuration instance
*
* @see GenericObjectPool#getMinEvictableIdleTimeMillis()
* @see GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()
+ * @deprecated Use {@link #setSoftMinEvictableIdleTime(Duration)}.
*/
+ @Deprecated
public void setMinEvictableIdleTimeMillis(final long minEvictableIdleTimeMillis) {
this.minEvictableIdleTime = Duration.ofMillis(minEvictableIdleTimeMillis);
}
@@ -370,9 +411,26 @@ public abstract class BaseObjectPoolConfig<T> extends BaseObject implements Clon
* @return The current setting of {@code softMinEvictableIdleTime}
* for this configuration instance
*
- * @see GenericObjectPool#getSoftMinEvictableIdleTimeMillis()
- * @see GenericKeyedObjectPool#getSoftMinEvictableIdleTimeMillis()
+ * @see GenericObjectPool#getSoftMinEvictableIdleTime()
+ * @see GenericKeyedObjectPool#getSoftMinEvictableIdleTime()
+ * @since 2.10.0
+ */
+ public Duration getSoftMinEvictableIdleTime() {
+ return softMinEvictableIdleTime;
+ }
+
+ /**
+ * Gets the value for the {@code softMinEvictableIdleTime}
+ * configuration attribute for pools created with this configuration
+ * instance.
+ *
+ * @return The current setting of {@code softMinEvictableIdleTime}
+ * for this configuration instance
+ *
+ * @see GenericObjectPool#getSoftMinEvictableIdleTime()
+ * @see GenericKeyedObjectPool#getSoftMinEvictableIdleTime()
*/
+ @Deprecated
public long getSoftMinEvictableIdleTimeMillis() {
return softMinEvictableIdleTime.toMillis();
}
@@ -388,13 +446,32 @@ public abstract class BaseObjectPoolConfig<T> extends BaseObject implements Clon
*
* @see GenericObjectPool#getSoftMinEvictableIdleTimeMillis()
* @see GenericKeyedObjectPool#getSoftMinEvictableIdleTimeMillis()
+ * @deprecated Use {@link #setSoftMinEvictableIdleTime(Duration)}.
*/
+ @Deprecated
public void setSoftMinEvictableIdleTimeMillis(
final long softMinEvictableIdleTimeMillis) {
this.softMinEvictableIdleTime = Duration.ofMillis(softMinEvictableIdleTimeMillis);
}
/**
+ * Sets the value for the {@code softMinEvictableIdleTime}
+ * configuration attribute for pools created with this configuration
+ * instance.
+ *
+ * @param softMinEvictableIdleTime The new setting of
+ * {@code softMinEvictableIdleTime} for this configuration
+ * instance
+ *
+ * @see GenericObjectPool#getSoftMinEvictableIdleTime()
+ * @see GenericKeyedObjectPool#getSoftMinEvictableIdleTime()
+ * @since 2.10.0
+ */
+ public void setSoftMinEvictableIdleTime(final Duration softMinEvictableIdleTime) {
+ this.softMinEvictableIdleTime = softMinEvictableIdleTime;
+ }
+
+ /**
* Gets the value for the {@code numTestsPerEvictionRun} configuration
* attribute for pools created with this configuration instance.
*
@@ -431,12 +508,45 @@ public abstract class BaseObjectPoolConfig<T> extends BaseObject implements Clon
*
* @see GenericObjectPool#getEvictorShutdownTimeoutMillis()
* @see GenericKeyedObjectPool#getEvictorShutdownTimeoutMillis()
+ * @deprecated Use {@link #getEvictorShutdownTimeout()}.
*/
+ @Deprecated
public long getEvictorShutdownTimeoutMillis() {
return evictorShutdownTimeout.toMillis();
}
/**
+ * Gets the value for the {@code evictorShutdownTimeout} configuration
+ * attribute for pools created with this configuration instance.
+ *
+ * @return The current setting of {@code evictorShutdownTimeout} for
+ * this configuration instance
+ *
+ * @see GenericObjectPool#getEvictorShutdownTimeout()
+ * @see GenericKeyedObjectPool#getEvictorShutdownTimeout()
+ * @since 2.10.0
+ */
+ public Duration getEvictorShutdownTimeout() {
+ return evictorShutdownTimeout;
+ }
+
+ /**
+ * Sets the value for the {@code evictorShutdownTimeout} configuration
+ * attribute for pools created with this configuration instance.
+ *
+ * @param evictorShutdownTimeoutMillis The new setting of
+ * {@code evictorShutdownTimeout} for this configuration
+ * instance
+ *
+ * @see GenericObjectPool#getEvictorShutdownTimeout()
+ * @see GenericKeyedObjectPool#getEvictorShutdownTimeout()
+ * @since 2.10.0
+ */
+ public void setEvictorShutdownTimeoutMillis(final Duration evictorShutdownTimeoutMillis) {
+ this.evictorShutdownTimeout = evictorShutdownTimeoutMillis;
+ }
+
+ /**
* Sets the value for the {@code evictorShutdownTimeout} configuration
* attribute for pools created with this configuration instance.
*
@@ -446,9 +556,10 @@ public abstract class BaseObjectPoolConfig<T> extends BaseObject implements Clon
*
* @see GenericObjectPool#getEvictorShutdownTimeoutMillis()
* @see GenericKeyedObjectPool#getEvictorShutdownTimeoutMillis()
+ * @deprecated Use {@link #setEvictorShutdownTimeoutMillis(Duration)}.
*/
- public void setEvictorShutdownTimeoutMillis(
- final long evictorShutdownTimeoutMillis) {
+ @Deprecated
+ public void setEvictorShutdownTimeoutMillis(final long evictorShutdownTimeoutMillis) {
this.evictorShutdownTimeout = Duration.ofMillis(evictorShutdownTimeoutMillis);
}
@@ -575,9 +686,26 @@ public abstract class BaseObjectPoolConfig<T> extends BaseObject implements Clon
* @return The current setting of {@code timeBetweenEvictionRuns} for
* this configuration instance
*
+ * @see GenericObjectPool#getTimeBetweenEvictionRuns()
+ * @see GenericKeyedObjectPool#getTimeBetweenEvictionRuns()
+ * @since 2.10.0
+ */
+ public Duration getTimeBetweenEvictionRuns() {
+ return timeBetweenEvictionRuns;
+ }
+
+ /**
+ * Gets the value for the {@code timeBetweenEvictionRuns} configuration
+ * attribute for pools created with this configuration instance.
+ *
+ * @return The current setting of {@code timeBetweenEvictionRuns} for
+ * this configuration instance
+ *
* @see GenericObjectPool#getTimeBetweenEvictionRunsMillis()
* @see GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()
+ * @deprecated Use {@link #getTimeBetweenEvictionRuns()}.
*/
+ @Deprecated
public long getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRuns.toMillis();
}
@@ -590,11 +718,28 @@ public abstract class BaseObjectPoolConfig<T> extends BaseObject implements Clon
* {@code timeBetweenEvictionRuns} for this configuration
* instance
*
+ * @see GenericObjectPool#getTimeBetweenEvictionRuns()
+ * @see GenericKeyedObjectPool#getTimeBetweenEvictionRuns()
+ * @since 2.10.0
+ */
+ public void setTimeBetweenEvictionRuns(final Duration timeBetweenEvictionRunsMillis) {
+ this.timeBetweenEvictionRuns = timeBetweenEvictionRunsMillis;
+ }
+
+ /**
+ * Sets the value for the {@code timeBetweenEvictionRuns} configuration
+ * attribute for pools created with this configuration instance.
+ *
+ * @param timeBetweenEvictionRunsMillis The new setting of
+ * {@code timeBetweenEvictionRuns} for this configuration
+ * instance
+ *
* @see GenericObjectPool#getTimeBetweenEvictionRunsMillis()
* @see GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()
+ * @deprecated Use {@link #setTimeBetweenEvictionRuns(Duration)}.
*/
- public void setTimeBetweenEvictionRunsMillis(
- final long timeBetweenEvictionRunsMillis) {
+ @Deprecated
+ public void setTimeBetweenEvictionRunsMillis(final long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRuns = Duration.ofMillis(timeBetweenEvictionRunsMillis);
}
diff --git a/src/main/java/org/apache/commons/pool2/impl/LinkedBlockingDeque.java b/src/main/java/org/apache/commons/pool2/impl/LinkedBlockingDeque.java
index e024546..1a48902 100644
--- a/src/main/java/org/apache/commons/pool2/impl/LinkedBlockingDeque.java
+++ b/src/main/java/org/apache/commons/pool2/impl/LinkedBlockingDeque.java
@@ -17,6 +17,7 @@
package org.apache.commons.pool2.impl;
import java.io.Serializable;
+import java.time.Duration;
import java.util.AbstractQueue;
import java.util.Collection;
import java.util.Deque;
@@ -91,7 +92,147 @@ class LinkedBlockingDeque<E> extends AbstractQueue<E>
* implementation, so a lot of method specs are duplicated here.
*/
- private static final long serialVersionUID = -387911632671998426L;
+ /**
+ * Base class for Iterators for LinkedBlockingDeque
+ */
+ private abstract class AbstractItr implements Iterator<E> {
+ /**
+ * The next node to return in next()
+ */
+ Node<E> next;
+
+ /**
+ * nextItem holds on to item fields because once we claim that
+ * an element exists in hasNext(), we must return item read
+ * under lock (in advance()) even if it was in the process of
+ * being removed when hasNext() was called.
+ */
+ E nextItem;
+
+ /**
+ * Node returned by most recent call to next. Needed by remove.
+ * Reset to null if this element is deleted by a call to remove.
+ */
+ private Node<E> lastRet;
+
+ /**
+ * Create a new iterator. Sets the initial position.
+ */
+ AbstractItr() {
+ // set to initial position
+ lock.lock();
+ try {
+ next = firstNode();
+ nextItem = next == null ? null : next.item;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Advances next.
+ */
+ void advance() {
+ lock.lock();
+ try {
+ // assert next != null;
+ next = succ(next);
+ nextItem = next == null ? null : next.item;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Obtain the first node to be returned by the iterator.
+ *
+ * @return first node
+ */
+ abstract Node<E> firstNode();
+
+ @Override
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ @Override
+ public E next() {
+ if (next == null) {
+ throw new NoSuchElementException();
+ }
+ lastRet = next;
+ final E x = nextItem;
+ advance();
+ return x;
+ }
+
+ /**
+ * For a given node, obtain the next node to be returned by the
+ * iterator.
+ *
+ * @param n given node
+ *
+ * @return next node
+ */
+ abstract Node<E> nextNode(Node<E> n);
+
+ @Override
+ public void remove() {
+ final Node<E> n = lastRet;
+ if (n == null) {
+ throw new IllegalStateException();
+ }
+ lastRet = null;
+ lock.lock();
+ try {
+ if (n.item != null) {
+ unlink(n);
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Returns the successor node of the given non-null, but
+ * possibly previously deleted, node.
+ *
+ * @param n node whose successor is sought
+ * @return successor node
+ */
+ private Node<E> succ(Node<E> n) {
+ // Chains of deleted nodes ending in null or self-links
+ // are possible if multiple interior nodes are removed.
+ for (;;) {
+ final Node<E> s = nextNode(n);
+ if (s == null) {
+ return null;
+ } else if (s.item != null) {
+ return s;
+ } else if (s == n) {
+ return firstNode();
+ } else {
+ n = s;
+ }
+ }
+ }
+ }
+
+ /** Descending iterator */
+ private class DescendingItr extends AbstractItr {
+ @Override
+ Node<E> firstNode() { return last; }
+ @Override
+ Node<E> nextNode(final Node<E> n) { return n.prev; }
+ }
+
+ /** Forward iterator */
+ private class Itr extends AbstractItr {
+ @Override
+ Node<E> firstNode() { return first; }
+ @Override
+ Node<E> nextNode(final Node<E> n) { return n.next; }
+ }
/**
* Doubly-linked list node class.
@@ -134,6 +275,8 @@ class LinkedBlockingDeque<E> extends AbstractQueue<E>
}
}
+ private static final long serialVersionUID = -387911632671998426L;
+
/**
* Pointer to first node.
* Invariant: (first == null && last == null) ||
@@ -181,6 +324,34 @@ class LinkedBlockingDeque<E> extends AbstractQueue<E>
this(Integer.MAX_VALUE, fairness);
}
+
+ // Basic linking and unlinking operations, called only while holding lock
+
+ /**
+ * Creates a {@code LinkedBlockingDeque} with a capacity of
+ * {@link Integer#MAX_VALUE}, initially containing the elements of
+ * the given collection, added in traversal order of the
+ * collection's iterator.
+ *
+ * @param c the collection of elements to initially contain
+ * @throws NullPointerException if the specified collection or any
+ * of its elements are null
+ */
+ public LinkedBlockingDeque(final Collection<? extends E> c) {
+ this(Integer.MAX_VALUE);
+ lock.lock(); // Never contended, but necessary for visibility
+ try {
+ for (final E e : c) {
+ Objects.requireNonNull(e);
+ if (!linkLast(e)) {
+ throw new IllegalStateException("Deque full");
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
/**
* Creates a {@code LinkedBlockingDeque} with the given (fixed) capacity.
*
@@ -211,480 +382,477 @@ class LinkedBlockingDeque<E> extends AbstractQueue<E>
}
/**
- * Creates a {@code LinkedBlockingDeque} with a capacity of
- * {@link Integer#MAX_VALUE}, initially containing the elements of
- * the given collection, added in traversal order of the
- * collection's iterator.
- *
- * @param c the collection of elements to initially contain
- * @throws NullPointerException if the specified collection or any
- * of its elements are null
+ * {@inheritDoc}
*/
- public LinkedBlockingDeque(final Collection<? extends E> c) {
- this(Integer.MAX_VALUE);
- lock.lock(); // Never contended, but necessary for visibility
- try {
- for (final E e : c) {
- Objects.requireNonNull(e);
- if (!linkLast(e)) {
- throw new IllegalStateException("Deque full");
- }
- }
- } finally {
- lock.unlock();
- }
+ @Override
+ public boolean add(final E e) {
+ addLast(e);
+ return true;
}
-
- // Basic linking and unlinking operations, called only while holding lock
-
/**
- * Links provided element as first element, or returns false if full.
- *
- * @param e The element to link as the first element.
- *
- * @return {@code true} if successful, otherwise {@code false}
+ * {@inheritDoc}
*/
- private boolean linkFirst(final E e) {
- // assert lock.isHeldByCurrentThread();
- if (count >= capacity) {
- return false;
- }
- final Node<E> f = first;
- final Node<E> x = new Node<>(e, null, f);
- first = x;
- if (last == null) {
- last = x;
- } else {
- f.prev = x;
+ @Override
+ public void addFirst(final E e) {
+ if (!offerFirst(e)) {
+ throw new IllegalStateException("Deque full");
}
- ++count;
- notEmpty.signal();
- return true;
}
+ // BlockingDeque methods
+
/**
- * Links provided element as last element, or returns false if full.
- *
- * @param e The element to link as the last element.
- *
- * @return {@code true} if successful, otherwise {@code false}
+ * {@inheritDoc}
*/
- private boolean linkLast(final E e) {
- // assert lock.isHeldByCurrentThread();
- if (count >= capacity) {
- return false;
- }
- final Node<E> l = last;
- final Node<E> x = new Node<>(e, l, null);
- last = x;
- if (first == null) {
- first = x;
- } else {
- l.next = x;
+ @Override
+ public void addLast(final E e) {
+ if (!offerLast(e)) {
+ throw new IllegalStateException("Deque full");
}
- ++count;
- notEmpty.signal();
- return true;
}
/**
- * Removes and returns the first element, or null if empty.
- *
- * @return The first element or {@code null} if empty
+ * Atomically removes all of the elements from this deque.
+ * The deque will be empty after this call returns.
*/
- private E unlinkFirst() {
- // assert lock.isHeldByCurrentThread();
- final Node<E> f = first;
- if (f == null) {
- return null;
- }
- final Node<E> n = f.next;
- final E item = f.item;
- f.item = null;
- f.next = f; // help GC
- first = n;
- if (n == null) {
- last = null;
- } else {
- n.prev = null;
+ @Override
+ public void clear() {
+ lock.lock();
+ try {
+ for (Node<E> f = first; f != null;) {
+ f.item = null;
+ final Node<E> n = f.next;
+ f.prev = null;
+ f.next = null;
+ f = n;
+ }
+ first = last = null;
+ count = 0;
+ notFull.signalAll();
+ } finally {
+ lock.unlock();
}
- --count;
- notFull.signal();
- return item;
}
/**
- * Removes and returns the last element, or null if empty.
+ * Returns {@code true} if this deque contains the specified element.
+ * More formally, returns {@code true} if and only if this deque contains
+ * at least one element {@code e} such that {@code o.equals(e)}.
*
- * @return The first element or {@code null} if empty
+ * @param o object to be checked for containment in this deque
+ * @return {@code true} if this deque contains the specified element
*/
- private E unlinkLast() {
- // assert lock.isHeldByCurrentThread();
- final Node<E> l = last;
- if (l == null) {
- return null;
+ @Override
+ public boolean contains(final Object o) {
+ if (o == null) {
+ return false;
}
- final Node<E> p = l.prev;
- final E item = l.item;
- l.item = null;
- l.prev = l; // help GC
- last = p;
- if (p == null) {
- first = null;
- } else {
- p.next = null;
+ lock.lock();
+ try {
+ for (Node<E> p = first; p != null; p = p.next) {
+ if (o.equals(p.item)) {
+ return true;
+ }
+ }
+ return false;
+ } finally {
+ lock.unlock();
}
- --count;
- notFull.signal();
- return item;
}
/**
- * Unlinks the provided node.
- *
- * @param x The node to unlink
+ * {@inheritDoc}
*/
- private void unlink(final Node<E> x) {
- // assert lock.isHeldByCurrentThread();
- final Node<E> p = x.prev;
- final Node<E> n = x.next;
- if (p == null) {
- unlinkFirst();
- } else if (n == null) {
- unlinkLast();
- } else {
- p.next = n;
- n.prev = p;
- x.item = null;
- // Don't mess with x's links. They may still be in use by
- // an iterator.
- --count;
- notFull.signal();
- }
+ @Override
+ public Iterator<E> descendingIterator() {
+ return new DescendingItr();
}
- // BlockingDeque methods
+ /**
+ * Drains the queue to the specified collection.
+ *
+ * @param c The collection to add the elements to
+ *
+ * @return number of elements added to the collection
+ *
+ * @throws UnsupportedOperationException if the add operation is not
+ * supported by the specified collection
+ * @throws ClassCastException if the class of the elements held by this
+ * collection prevents them from being added to the specified
+ * collection
+ * @throws NullPointerException if c is null
+ * @throws IllegalArgumentException if c is this instance
+ */
+ public int drainTo(final Collection<? super E> c) {
+ return drainTo(c, Integer.MAX_VALUE);
+ }
/**
- * {@inheritDoc}
+ * Drains no more than the specified number of elements from the queue to the
+ * specified collection.
+ *
+ * @param c collection to add the elements to
+ * @param maxElements maximum number of elements to remove from the queue
+ *
+ * @return number of elements added to the collection
+ * @throws UnsupportedOperationException if the add operation is not
+ * supported by the specified collection
+ * @throws ClassCastException if the class of the elements held by this
+ * collection prevents them from being added to the specified
+ * collection
+ * @throws NullPointerException if c is null
+ * @throws IllegalArgumentException if c is this instance
*/
- @Override
- public void addFirst(final E e) {
- if (!offerFirst(e)) {
- throw new IllegalStateException("Deque full");
+ public int drainTo(final Collection<? super E> c, final int maxElements) {
+ Objects.requireNonNull(c, "c");
+ if (c == this) {
+ throw new IllegalArgumentException();
+ }
+ lock.lock();
+ try {
+ final int n = Math.min(maxElements, count);
+ for (int i = 0; i < n; i++) {
+ c.add(first.item); // In this order, in case add() throws.
+ unlinkFirst();
+ }
+ return n;
+ } finally {
+ lock.unlock();
}
}
/**
- * {@inheritDoc}
+ * Retrieves, but does not remove, the head of the queue represented by
+ * this deque. This method differs from {@link #peek peek} only in that
+ * it throws an exception if this deque is empty.
+ *
+ * <p>This method is equivalent to {@link #getFirst() getFirst}.
+ *
+ * @return the head of the queue represented by this deque
+ * @throws NoSuchElementException if this deque is empty
*/
@Override
- public void addLast(final E e) {
- if (!offerLast(e)) {
- throw new IllegalStateException("Deque full");
- }
+ public E element() {
+ return getFirst();
}
/**
* {@inheritDoc}
*/
@Override
- public boolean offerFirst(final E e) {
- Objects.requireNonNull(e, "e");
- lock.lock();
- try {
- return linkFirst(e);
- } finally {
- lock.unlock();
+ public E getFirst() {
+ final E x = peekFirst();
+ if (x == null) {
+ throw new NoSuchElementException();
}
+ return x;
}
/**
* {@inheritDoc}
*/
@Override
- public boolean offerLast(final E e) {
- Objects.requireNonNull(e, "e");
- lock.lock();
- try {
- return linkLast(e);
- } finally {
- lock.unlock();
+ public E getLast() {
+ final E x = peekLast();
+ if (x == null) {
+ throw new NoSuchElementException();
}
+ return x;
}
/**
- * Links the provided element as the first in the queue, waiting until there
- * is space to do so if the queue is full.
- *
- * @param e element to link
+ * Returns the length of the queue of threads waiting to take instances from this deque. See disclaimer on accuracy
+ * in {@link java.util.concurrent.locks.ReentrantLock#getWaitQueueLength(Condition)}.
*
- * @throws NullPointerException if e is null
- * @throws InterruptedException if the thread is interrupted whilst waiting
- * for space
+ * @return number of threads waiting on this deque's notEmpty condition.
*/
- public void putFirst(final E e) throws InterruptedException {
- Objects.requireNonNull(e, "e");
+ public int getTakeQueueLength() {
lock.lock();
try {
- while (!linkFirst(e)) {
- notFull.await();
- }
+ return lock.getWaitQueueLength(notEmpty);
} finally {
lock.unlock();
}
}
/**
- * Links the provided element as the last in the queue, waiting until there
- * is space to do so if the queue is full.
- *
- * @param e element to link
+ * Returns true if there are threads waiting to take instances from this deque. See disclaimer on accuracy in
+ * {@link java.util.concurrent.locks.ReentrantLock#hasWaiters(Condition)}.
*
- * @throws NullPointerException if e is null
- * @throws InterruptedException if the thread is interrupted whilst waiting
- * for space
+ * @return true if there is at least one thread waiting on this deque's notEmpty condition.
*/
- public void putLast(final E e) throws InterruptedException {
- Objects.requireNonNull(e, "e");
+ public boolean hasTakeWaiters() {
lock.lock();
try {
- while (!linkLast(e)) {
- notFull.await();
- }
+ return lock.hasWaiters(notEmpty);
} finally {
lock.unlock();
}
}
/**
- * Links the provided element as the first in the queue, waiting up to the
- * specified time to do so if the queue is full.
- *
- * @param e element to link
- * @param timeout length of time to wait
- * @param unit units that timeout is expressed in
- *
- * @return {@code true} if successful, otherwise {@code false}
- *
- * @throws NullPointerException if e is null
- * @throws InterruptedException if the thread is interrupted whilst waiting
- * for space
+ * Interrupts the threads currently waiting to take an object from the pool. See disclaimer on accuracy in
+ * {@link java.util.concurrent.locks.ReentrantLock#getWaitingThreads(Condition)}.
*/
- public boolean offerFirst(final E e, final long timeout, final TimeUnit unit)
- throws InterruptedException {
- Objects.requireNonNull(e, "e");
- long nanos = unit.toNanos(timeout);
- lock.lockInterruptibly();
+ public void interuptTakeWaiters() {
+ lock.lock();
try {
- while (!linkFirst(e)) {
- if (nanos <= 0) {
- return false;
- }
- nanos = notFull.awaitNanos(nanos);
- }
- return true;
+ lock.interruptWaiters(notEmpty);
} finally {
lock.unlock();
}
}
/**
- * Links the provided element as the last in the queue, waiting up to the
- * specified time to do so if the queue is full.
- *
- * @param e element to link
- * @param timeout length of time to wait
- * @param unit units that timeout is expressed in
+ * Returns an iterator over the elements in this deque in proper sequence.
+ * The elements will be returned in order from first (head) to last (tail).
+ * The returned {@code Iterator} is a "weakly consistent" iterator that
+ * will never throw {@link java.util.ConcurrentModificationException
+ * ConcurrentModificationException},
+ * and guarantees to traverse elements as they existed upon
+ * construction of the iterator, and may (but is not guaranteed to)
+ * reflect any modifications subsequent to construction.
*
- * @return {@code true} if successful, otherwise {@code false}
+ * @return an iterator over the elements in this deque in proper sequence
+ */
+ @Override
+ public Iterator<E> iterator() {
+ return new Itr();
+ }
+
+ /**
+ * Links provided element as first element, or returns false if full.
*
- * @throws NullPointerException if e is null
- * @throws InterruptedException if the thread is interrupted whist waiting
- * for space
+ * @param e The element to link as the first element.
+ *
+ * @return {@code true} if successful, otherwise {@code false}
*/
- public boolean offerLast(final E e, final long timeout, final TimeUnit unit)
- throws InterruptedException {
- Objects.requireNonNull(e, "e");
- long nanos = unit.toNanos(timeout);
- lock.lockInterruptibly();
- try {
- while (!linkLast(e)) {
- if (nanos <= 0) {
- return false;
- }
- nanos = notFull.awaitNanos(nanos);
- }
- return true;
- } finally {
- lock.unlock();
+ private boolean linkFirst(final E e) {
+ // assert lock.isHeldByCurrentThread();
+ if (count >= capacity) {
+ return false;
+ }
+ final Node<E> f = first;
+ final Node<E> x = new Node<>(e, null, f);
+ first = x;
+ if (last == null) {
+ last = x;
+ } else {
+ f.prev = x;
}
+ ++count;
+ notEmpty.signal();
+ return true;
}
/**
- * {@inheritDoc}
+ * Links provided element as last element, or returns false if full.
+ *
+ * @param e The element to link as the last element.
+ *
+ * @return {@code true} if successful, otherwise {@code false}
*/
- @Override
- public E removeFirst() {
- final E x = pollFirst();
- if (x == null) {
- throw new NoSuchElementException();
+ private boolean linkLast(final E e) {
+ // assert lock.isHeldByCurrentThread();
+ if (count >= capacity) {
+ return false;
}
- return x;
+ final Node<E> l = last;
+ final Node<E> x = new Node<>(e, l, null);
+ last = x;
+ if (first == null) {
+ first = x;
+ } else {
+ l.next = x;
+ }
+ ++count;
+ notEmpty.signal();
+ return true;
}
/**
* {@inheritDoc}
*/
@Override
- public E removeLast() {
- final E x = pollLast();
- if (x == null) {
- throw new NoSuchElementException();
- }
- return x;
+ public boolean offer(final E e) {
+ return offerLast(e);
}
- @Override
- public E pollFirst() {
- lock.lock();
- try {
- return unlinkFirst();
- } finally {
- lock.unlock();
- }
+ /**
+ * Links the provided element as the last in the queue, waiting up to the
+ * specified time to do so if the queue is full.
+ * <p>
+ * This method is equivalent to {@link #offerLast(Object, long, TimeUnit)}
+ *
+ * @param e element to link
+ * @param timeout length of time to wait
+ *
+ * @return {@code true} if successful, otherwise {@code false}
+ *
+ * @throws NullPointerException if e is null
+ * @throws InterruptedException if the thread is interrupted whilst waiting
+ * for space
+ */
+ boolean offer(final E e, final Duration timeout)
+ throws InterruptedException {
+ return offerLast(e, timeout);
}
- @Override
- public E pollLast() {
- lock.lock();
- try {
- return unlinkLast();
- } finally {
- lock.unlock();
- }
+ /**
+ * Links the provided element as the last in the queue, waiting up to the
+ * specified time to do so if the queue is full.
+ * <p>
+ * This method is equivalent to {@link #offerLast(Object, long, TimeUnit)}
+ *
+ * @param e element to link
+ * @param timeout length of time to wait
+ * @param unit units that timeout is expressed in
+ *
+ * @return {@code true} if successful, otherwise {@code false}
+ *
+ * @throws NullPointerException if e is null
+ * @throws InterruptedException if the thread is interrupted whilst waiting
+ * for space
+ */
+ public boolean offer(final E e, final long timeout, final TimeUnit unit)
+ throws InterruptedException {
+ return offerLast(e, timeout, unit);
}
/**
- * Unlinks the first element in the queue, waiting until there is an element
- * to unlink if the queue is empty.
- *
- * @return the unlinked element
- * @throws InterruptedException if the current thread is interrupted
+ * {@inheritDoc}
*/
- public E takeFirst() throws InterruptedException {
+ @Override
+ public boolean offerFirst(final E e) {
+ Objects.requireNonNull(e, "e");
lock.lock();
try {
- E x;
- while ( (x = unlinkFirst()) == null) {
- notEmpty.await();
- }
- return x;
+ return linkFirst(e);
} finally {
lock.unlock();
}
}
/**
- * Unlinks the last element in the queue, waiting until there is an element
- * to unlink if the queue is empty.
+ * Links the provided element as the first in the queue, waiting up to the
+ * specified time to do so if the queue is full.
*
- * @return the unlinked element
- * @throws InterruptedException if the current thread is interrupted
+ * @param e element to link
+ * @param timeout length of time to wait
+ *
+ * @return {@code true} if successful, otherwise {@code false}
+ *
+ * @throws NullPointerException if e is null
+ * @throws InterruptedException if the thread is interrupted whilst waiting
+ * for space
*/
- public E takeLast() throws InterruptedException {
- lock.lock();
+ public boolean offerFirst(final E e, final Duration timeout)
+ throws InterruptedException {
+ Objects.requireNonNull(e, "e");
+ long nanos = timeout.toNanos();
+ lock.lockInterruptibly();
try {
- E x;
- while ( (x = unlinkLast()) == null) {
- notEmpty.await();
+ while (!linkFirst(e)) {
+ if (nanos <= 0) {
+ return false;
+ }
+ nanos = notFull.awaitNanos(nanos);
}
- return x;
+ return true;
} finally {
lock.unlock();
}
}
/**
- * Unlinks the first element in the queue, waiting up to the specified time
- * to do so if the queue is empty.
+ * Links the provided element as the first in the queue, waiting up to the
+ * specified time to do so if the queue is full.
*
+ * @param e element to link
* @param timeout length of time to wait
* @param unit units that timeout is expressed in
*
- * @return the unlinked element
- * @throws InterruptedException if the current thread is interrupted
+ * @return {@code true} if successful, otherwise {@code false}
+ *
+ * @throws NullPointerException if e is null
+ * @throws InterruptedException if the thread is interrupted whilst waiting
+ * for space
*/
- public E pollFirst(final long timeout, final TimeUnit unit)
+ public boolean offerFirst(final E e, final long timeout, final TimeUnit unit)
throws InterruptedException {
- long nanos = unit.toNanos(timeout);
- lock.lockInterruptibly();
+ return offerFirst(e, PoolImplUtils.toDuration(timeout, unit));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean offerLast(final E e) {
+ Objects.requireNonNull(e, "e");
+ lock.lock();
try {
- E x;
- while ( (x = unlinkFirst()) == null) {
- if (nanos <= 0) {
- return null;
- }
- nanos = notEmpty.awaitNanos(nanos);
- }
- return x;
+ return linkLast(e);
} finally {
lock.unlock();
}
}
/**
- * Unlinks the last element in the queue, waiting up to the specified time
- * to do so if the queue is empty.
+ * Links the provided element as the last in the queue, waiting up to the
+ * specified time to do so if the queue is full.
*
+ * @param e element to link
* @param timeout length of time to wait
- * @param unit units that timeout is expressed in
*
- * @return the unlinked element
- * @throws InterruptedException if the current thread is interrupted
+ * @return {@code true} if successful, otherwise {@code false}
+ *
+ * @throws NullPointerException if e is null
+ * @throws InterruptedException if the thread is interrupted whist waiting
+ * for space
*/
- public E pollLast(final long timeout, final TimeUnit unit)
+ boolean offerLast(final E e, final Duration timeout)
throws InterruptedException {
- long nanos = unit.toNanos(timeout);
+ Objects.requireNonNull(e, "e");
+ long nanos = timeout.toNanos();
lock.lockInterruptibly();
try {
- E x;
- while ( (x = unlinkLast()) == null) {
+ while (!linkLast(e)) {
if (nanos <= 0) {
- return null;
+ return false;
}
- nanos = notEmpty.awaitNanos(nanos);
+ nanos = notFull.awaitNanos(nanos);
}
- return x;
+ return true;
} finally {
lock.unlock();
}
}
/**
- * {@inheritDoc}
+ * Links the provided element as the last in the queue, waiting up to the
+ * specified time to do so if the queue is full.
+ *
+ * @param e element to link
+ * @param timeout length of time to wait
+ * @param unit units that timeout is expressed in
+ *
+ * @return {@code true} if successful, otherwise {@code false}
+ *
+ * @throws NullPointerException if e is null
+ * @throws InterruptedException if the thread is interrupted whist waiting
+ * for space
*/
+ public boolean offerLast(final E e, final long timeout, final TimeUnit unit) throws InterruptedException {
+ return offerLast(e, PoolImplUtils.toDuration(timeout, unit));
+ }
+
@Override
- public E getFirst() {
- final E x = peekFirst();
- if (x == null) {
- throw new NoSuchElementException();
- }
- return x;
+ public E peek() {
+ return peekFirst();
}
- /**
- * {@inheritDoc}
- */
- @Override
- public E getLast() {
- final E x = peekLast();
- if (x == null) {
- throw new NoSuchElementException();
- }
- return x;
- }
+ // BlockingQueue methods
@Override
public E peekFirst() {
@@ -707,60 +875,157 @@ class LinkedBlockingDeque<E> extends AbstractQueue<E>
}
@Override
- public boolean removeFirstOccurrence(final Object o) {
- if (o == null) {
- return false;
- }
+ public E poll() {
+ return pollFirst();
+ }
+
+ /**
+ * Unlinks the first element in the queue, waiting up to the specified time
+ * to do so if the queue is empty.
+ *
+ * <p>This method is equivalent to {@link #pollFirst(long, TimeUnit)}.
+ *
+ * @param timeout length of time to wait
+ *
+ * @return the unlinked element
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ E poll(final Duration timeout) throws InterruptedException {
+ return pollFirst(timeout);
+ }
+
+ /**
+ * Unlinks the first element in the queue, waiting up to the specified time
+ * to do so if the queue is empty.
+ *
+ * <p>This method is equivalent to {@link #pollFirst(long, TimeUnit)}.
+ *
+ * @param timeout length of time to wait
+ * @param unit units that timeout is expressed in
+ *
+ * @return the unlinked element
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public E poll(final long timeout, final TimeUnit unit) throws InterruptedException {
+ return pollFirst(timeout, unit);
+ }
+
+ @Override
+ public E pollFirst() {
lock.lock();
try {
- for (Node<E> p = first; p != null; p = p.next) {
- if (o.equals(p.item)) {
- unlink(p);
- return true;
+ return unlinkFirst();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Unlinks the first element in the queue, waiting up to the specified time
+ * to do so if the queue is empty.
+ *
+ * @param timeout length of time to wait
+ *
+ * @return the unlinked element
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ E pollFirst(final Duration timeout) throws InterruptedException {
+ long nanos = timeout.toNanos();
+ lock.lockInterruptibly();
+ try {
+ E x;
+ while ((x = unlinkFirst()) == null) {
+ if (nanos <= 0) {
+ return null;
}
+ nanos = notEmpty.awaitNanos(nanos);
}
- return false;
+ return x;
} finally {
lock.unlock();
}
}
+ /**
+ * Unlinks the first element in the queue, waiting up to the specified time
+ * to do so if the queue is empty.
+ *
+ * @param timeout length of time to wait
+ * @param unit units that timeout is expressed in
+ *
+ * @return the unlinked element
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public E pollFirst(final long timeout, final TimeUnit unit) throws InterruptedException {
+ return pollFirst(PoolImplUtils.toDuration(timeout, unit));
+ }
+
@Override
- public boolean removeLastOccurrence(final Object o) {
- if (o == null) {
- return false;
- }
+ public E pollLast() {
lock.lock();
try {
- for (Node<E> p = last; p != null; p = p.prev) {
- if (o.equals(p.item)) {
- unlink(p);
- return true;
+ return unlinkLast();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Unlinks the last element in the queue, waiting up to the specified time
+ * to do so if the queue is empty.
+ *
+ * @param timeout length of time to wait
+ *
+ * @return the unlinked element
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public E pollLast(final Duration timeout)
+ throws InterruptedException {
+ long nanos = timeout.toNanos();
+ lock.lockInterruptibly();
+ try {
+ E x;
+ while ( (x = unlinkLast()) == null) {
+ if (nanos <= 0) {
+ return null;
}
+ nanos = notEmpty.awaitNanos(nanos);
}
- return false;
+ return x;
} finally {
lock.unlock();
}
}
- // BlockingQueue methods
+ /**
+ * Unlinks the last element in the queue, waiting up to the specified time
+ * to do so if the queue is empty.
+ *
+ * @param timeout length of time to wait
+ * @param unit units that timeout is expressed in
+ *
+ * @return the unlinked element
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public E pollLast(final long timeout, final TimeUnit unit)
+ throws InterruptedException {
+ return pollLast(PoolImplUtils.toDuration(timeout, unit));
+ }
/**
* {@inheritDoc}
*/
@Override
- public boolean add(final E e) {
- addLast(e);
- return true;
+ public E pop() {
+ return removeFirst();
}
/**
* {@inheritDoc}
*/
@Override
- public boolean offer(final E e) {
- return offerLast(e);
+ public void push(final E e) {
+ addFirst(e);
}
/**
@@ -780,26 +1045,98 @@ class LinkedBlockingDeque<E> extends AbstractQueue<E>
}
/**
- * Links the provided element as the last in the queue, waiting up to the
- * specified time to do so if the queue is full.
- * <p>
- * This method is equivalent to {@link #offerLast(Object, long, TimeUnit)}
+ * Links the provided element as the first in the queue, waiting until there
+ * is space to do so if the queue is full.
*
- * @param e element to link
- * @param timeout length of time to wait
- * @param unit units that timeout is expressed in
+ * @param e element to link
*
- * @return {@code true} if successful, otherwise {@code false}
+ * @throws NullPointerException if e is null
+ * @throws InterruptedException if the thread is interrupted whilst waiting
+ * for space
+ */
+ public void putFirst(final E e) throws InterruptedException {
+ Objects.requireNonNull(e, "e");
+ lock.lock();
+ try {
+ while (!linkFirst(e)) {
+ notFull.await();
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Links the provided element as the last in the queue, waiting until there
+ * is space to do so if the queue is full.
+ *
+ * @param e element to link
*
* @throws NullPointerException if e is null
* @throws InterruptedException if the thread is interrupted whilst waiting
* for space
*/
- public boolean offer(final E e, final long timeout, final TimeUnit unit)
- throws InterruptedException {
- return offerLast(e, timeout, unit);
+ public void putLast(final E e) throws InterruptedException {
+ Objects.requireNonNull(e, "e");
+ lock.lock();
+ try {
+ while (!linkLast(e)) {
+ notFull.await();
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ // Stack methods
+
+ /**
+ * Reconstitutes this deque from a stream (that is,
+ * deserialize it).
+ * @param s the stream
+ */
+ private void readObject(final java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ count = 0;
+ first = null;
+ last = null;
+ // Read in all elements and place in queue
+ for (;;) {
+ @SuppressWarnings("unchecked")
+ final
+ E item = (E)s.readObject();
+ if (item == null) {
+ break;
+ }
+ add(item);
+ }
+ }
+
+ /**
+ * Returns the number of additional elements that this deque can ideally
+ * (in the absence of memory or resource constraints) accept without
+ * blocking. This is always equal to the initial capacity of this deque
+ * less the current {@code size} of this deque.
+ *
+ * <p>Note that you <em>cannot</em> always tell if an attempt to insert
+ * an element will succeed by inspecting {@code remainingCapacity}
+ * because it may be the case that another thread is about to
+ * insert or remove an element.
+ *
+ * @return The number of additional elements the queue is able to accept
+ */
+ public int remainingCapacity() {
+ lock.lock();
+ try {
+ return capacity - count;
+ } finally {
+ lock.unlock();
+ }
}
+ // Collection methods
+
/**
* Retrieves and removes the head of the queue represented by this deque.
* This method differs from {@link #poll poll} only in that it throws an
@@ -815,155 +1152,6 @@ class LinkedBlockingDeque<E> extends AbstractQueue<E>
return removeFirst();
}
- @Override
- public E poll() {
- return pollFirst();
- }
-
- /**
- * Unlinks the first element in the queue, waiting until there is an element
- * to unlink if the queue is empty.
- *
- * <p>This method is equivalent to {@link #takeFirst()}.
- *
- * @return the unlinked element
- * @throws InterruptedException if the current thread is interrupted
- */
- public E take() throws InterruptedException {
- return takeFirst();
- }
-
- /**
- * Unlinks the first element in the queue, waiting up to the specified time
- * to do so if the queue is empty.
- *
- * <p>This method is equivalent to {@link #pollFirst(long, TimeUnit)}.
- *
- * @param timeout length of time to wait
- * @param unit units that timeout is expressed in
- *
- * @return the unlinked element
- * @throws InterruptedException if the current thread is interrupted
- */
- public E poll(final long timeout, final TimeUnit unit) throws InterruptedException {
- return pollFirst(timeout, unit);
- }
-
- /**
- * Retrieves, but does not remove, the head of the queue represented by
- * this deque. This method differs from {@link #peek peek} only in that
- * it throws an exception if this deque is empty.
- *
- * <p>This method is equivalent to {@link #getFirst() getFirst}.
- *
- * @return the head of the queue represented by this deque
- * @throws NoSuchElementException if this deque is empty
- */
- @Override
- public E element() {
- return getFirst();
- }
-
- @Override
- public E peek() {
- return peekFirst();
- }
-
- /**
- * Returns the number of additional elements that this deque can ideally
- * (in the absence of memory or resource constraints) accept without
- * blocking. This is always equal to the initial capacity of this deque
- * less the current {@code size} of this deque.
- *
- * <p>Note that you <em>cannot</em> always tell if an attempt to insert
- * an element will succeed by inspecting {@code remainingCapacity}
- * because it may be the case that another thread is about to
- * insert or remove an element.
- *
- * @return The number of additional elements the queue is able to accept
- */
- public int remainingCapacity() {
- lock.lock();
- try {
- return capacity - count;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Drains the queue to the specified collection.
- *
- * @param c The collection to add the elements to
- *
- * @return number of elements added to the collection
- *
- * @throws UnsupportedOperationException if the add operation is not
- * supported by the specified collection
- * @throws ClassCastException if the class of the elements held by this
- * collection prevents them from being added to the specified
- * collection
- * @throws NullPointerException if c is null
- * @throws IllegalArgumentException if c is this instance
- */
- public int drainTo(final Collection<? super E> c) {
- return drainTo(c, Integer.MAX_VALUE);
- }
-
- /**
- * Drains no more than the specified number of elements from the queue to the
- * specified collection.
- *
- * @param c collection to add the elements to
- * @param maxElements maximum number of elements to remove from the queue
- *
- * @return number of elements added to the collection
- * @throws UnsupportedOperationException if the add operation is not
- * supported by the specified collection
- * @throws ClassCastException if the class of the elements held by this
- * collection prevents them from being added to the specified
- * collection
- * @throws NullPointerException if c is null
- * @throws IllegalArgumentException if c is this instance
- */
- public int drainTo(final Collection<? super E> c, final int maxElements) {
- Objects.requireNonNull(c, "c");
- if (c == this) {
- throw new IllegalArgumentException();
- }
- lock.lock();
- try {
- final int n = Math.min(maxElements, count);
- for (int i = 0; i < n; i++) {
- c.add(first.item); // In this order, in case add() throws.
- unlinkFirst();
- }
- return n;
- } finally {
- lock.unlock();
- }
- }
-
- // Stack methods
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void push(final E e) {
- addFirst(e);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public E pop() {
- return removeFirst();
- }
-
- // Collection methods
-
/**
* Removes the first occurrence of the specified element from this deque.
* If the deque does not contain the element, it is unchanged.
@@ -984,44 +1172,15 @@ class LinkedBlockingDeque<E> extends AbstractQueue<E>
}
/**
- * Returns the number of elements in this deque.
- *
- * @return the number of elements in this deque
- */
- @Override
- public int size() {
- lock.lock();
- try {
- return count;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Returns {@code true} if this deque contains the specified element.
- * More formally, returns {@code true} if and only if this deque contains
- * at least one element {@code e} such that {@code o.equals(e)}.
- *
- * @param o object to be checked for containment in this deque
- * @return {@code true} if this deque contains the specified element
+ * {@inheritDoc}
*/
@Override
- public boolean contains(final Object o) {
- if (o == null) {
- return false;
- }
- lock.lock();
- try {
- for (Node<E> p = first; p != null; p = p.next) {
- if (o.equals(p.item)) {
- return true;
- }
- }
- return false;
- } finally {
- lock.unlock();
+ public E removeFirst() {
+ final E x = pollFirst();
+ if (x == null) {
+ throw new NoSuchElementException();
}
+ return x;
}
/*
@@ -1065,29 +1224,20 @@ class LinkedBlockingDeque<E> extends AbstractQueue<E>
// }
// }
- /**
- * Returns an array containing all of the elements in this deque, in
- * proper sequence (from first to last element).
- *
- * <p>The returned array will be "safe" in that no references to it are
- * maintained by this deque. (In other words, this method must allocate
- * a new array). The caller is thus free to modify the returned array.
- *
- * <p>This method acts as bridge between array-based and collection-based
- * APIs.
- *
- * @return an array containing all of the elements in this deque
- */
@Override
- public Object[] toArray() {
+ public boolean removeFirstOccurrence(final Object o) {
+ if (o == null) {
+ return false;
+ }
lock.lock();
try {
- final Object[] a = new Object[count];
- int k = 0;
for (Node<E> p = first; p != null; p = p.next) {
- a[k++] = p.item;
+ if (o.equals(p.item)) {
+ unlink(p);
+ return true;
+ }
}
- return a;
+ return false;
} finally {
lock.unlock();
}
@@ -1096,315 +1246,262 @@ class LinkedBlockingDeque<E> extends AbstractQueue<E>
/**
* {@inheritDoc}
*/
- @SuppressWarnings("unchecked")
@Override
- public <T> T[] toArray(T[] a) {
+ public E removeLast() {
+ final E x = pollLast();
+ if (x == null) {
+ throw new NoSuchElementException();
+ }
+ return x;
+ }
+
+ @Override
+ public boolean removeLastOccurrence(final Object o) {
+ if (o == null) {
+ return false;
+ }
lock.lock();
try {
- if (a.length < count) {
- a = (T[])java.lang.reflect.Array.newInstance
- (a.getClass().getComponentType(), count);
- }
- int k = 0;
- for (Node<E> p = first; p != null; p = p.next) {
- a[k++] = (T)p.item;
- }
- if (a.length > k) {
- a[k] = null;
+ for (Node<E> p = last; p != null; p = p.prev) {
+ if (o.equals(p.item)) {
+ unlink(p);
+ return true;
+ }
}
- return a;
+ return false;
} finally {
lock.unlock();
}
}
+ /**
+ * Returns the number of elements in this deque.
+ *
+ * @return the number of elements in this deque
+ */
@Override
- public String toString() {
+ public int size() {
lock.lock();
try {
- return super.toString();
+ return count;
} finally {
lock.unlock();
}
}
/**
- * Atomically removes all of the elements from this deque.
- * The deque will be empty after this call returns.
- */
- @Override
- public void clear() {
+ * Unlinks the first element in the queue, waiting until there is an element
+ * to unlink if the queue is empty.
+ *
+ * <p>This method is equivalent to {@link #takeFirst()}.
+ *
+ * @return the unlinked element
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public E take() throws InterruptedException {
+ return takeFirst();
+ }
+
+ /**
+ * Unlinks the first element in the queue, waiting until there is an element
+ * to unlink if the queue is empty.
+ *
+ * @return the unlinked element
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public E takeFirst() throws InterruptedException {
lock.lock();
try {
- for (Node<E> f = first; f != null;) {
- f.item = null;
- final Node<E> n = f.next;
- f.prev = null;
- f.next = null;
- f = n;
+ E x;
+ while ( (x = unlinkFirst()) == null) {
+ notEmpty.await();
}
- first = last = null;
- count = 0;
- notFull.signalAll();
+ return x;
} finally {
lock.unlock();
}
}
/**
- * Returns an iterator over the elements in this deque in proper sequence.
- * The elements will be returned in order from first (head) to last (tail).
- * The returned {@code Iterator} is a "weakly consistent" iterator that
- * will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
+ * Unlinks the last element in the queue, waiting until there is an element
+ * to unlink if the queue is empty.
*
- * @return an iterator over the elements in this deque in proper sequence
+ * @return the unlinked element
+ * @throws InterruptedException if the current thread is interrupted
*/
- @Override
- public Iterator<E> iterator() {
- return new Itr();
+ public E takeLast() throws InterruptedException {
+ lock.lock();
+ try {
+ E x;
+ while ( (x = unlinkLast()) == null) {
+ notEmpty.await();
+ }
+ return x;
+ } finally {
+ lock.unlock();
+ }
}
/**
- * {@inheritDoc}
+ * Returns an array containing all of the elements in this deque, in
+ * proper sequence (from first to last element).
+ *
+ * <p>The returned array will be "safe" in that no references to it are
+ * maintained by this deque. (In other words, this method must allocate
+ * a new array). The caller is thus free to modify the returned array.
+ *
+ * <p>This method acts as bridge between array-based and collection-based
+ * APIs.
+ *
+ * @return an array containing all of the elements in this deque
*/
@Override
- public Iterator<E> descendingIterator() {
- return new DescendingItr();
+ public Object[] toArray() {
+ lock.lock();
+ try {
+ final Object[] a = new Object[count];
+ int k = 0;
+ for (Node<E> p = first; p != null; p = p.next) {
+ a[k++] = p.item;
+ }
+ return a;
+ } finally {
+ lock.unlock();
+ }
}
/**
- * Base class for Iterators for LinkedBlockingDeque
+ * {@inheritDoc}
*/
- private abstract class AbstractItr implements Iterator<E> {
- /**
- * The next node to return in next()
- */
- Node<E> next;
-
- /**
- * nextItem holds on to item fields because once we claim that
- * an element exists in hasNext(), we must return item read
- * under lock (in advance()) even if it was in the process of
- * being removed when hasNext() was called.
- */
- E nextItem;
-
- /**
- * Node returned by most recent call to next. Needed by remove.
- * Reset to null if this element is deleted by a call to remove.
- */
- private Node<E> lastRet;
-
- /**
- * Obtain the first node to be returned by the iterator.
- *
- * @return first node
- */
- abstract Node<E> firstNode();
-
- /**
- * For a given node, obtain the next node to be returned by the
- * iterator.
- *
- * @param n given node
- *
- * @return next node
- */
- abstract Node<E> nextNode(Node<E> n);
-
- /**
- * Create a new iterator. Sets the initial position.
- */
- AbstractItr() {
- // set to initial position
- lock.lock();
- try {
- next = firstNode();
- nextItem = next == null ? null : next.item;
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Returns the successor node of the given non-null, but
- * possibly previously deleted, node.
- *
- * @param n node whose successor is sought
- * @return successor node
- */
- private Node<E> succ(Node<E> n) {
- // Chains of deleted nodes ending in null or self-links
- // are possible if multiple interior nodes are removed.
- for (;;) {
- final Node<E> s = nextNode(n);
- if (s == null) {
- return null;
- } else if (s.item != null) {
- return s;
- } else if (s == n) {
- return firstNode();
- } else {
- n = s;
- }
- }
- }
-
- /**
- * Advances next.
- */
- void advance() {
- lock.lock();
- try {
- // assert next != null;
- next = succ(next);
- nextItem = next == null ? null : next.item;
- } finally {
- lock.unlock();
- }
- }
-
- @Override
- public boolean hasNext() {
- return next != null;
- }
-
- @Override
- public E next() {
- if (next == null) {
- throw new NoSuchElementException();
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> T[] toArray(T[] a) {
+ lock.lock();
+ try {
+ if (a.length < count) {
+ a = (T[])java.lang.reflect.Array.newInstance
+ (a.getClass().getComponentType(), count);
}
- lastRet = next;
- final E x = nextItem;
- advance();
- return x;
- }
-
- @Override
- public void remove() {
- final Node<E> n = lastRet;
- if (n == null) {
- throw new IllegalStateException();
+ int k = 0;
+ for (Node<E> p = first; p != null; p = p.next) {
+ a[k++] = (T)p.item;
}
- lastRet = null;
- lock.lock();
- try {
- if (n.item != null) {
- unlink(n);
- }
- } finally {
- lock.unlock();
+ if (a.length > k) {
+ a[k] = null;
}
+ return a;
+ } finally {
+ lock.unlock();
}
}
- /** Forward iterator */
- private class Itr extends AbstractItr {
- @Override
- Node<E> firstNode() { return first; }
- @Override
- Node<E> nextNode(final Node<E> n) { return n.next; }
- }
-
- /** Descending iterator */
- private class DescendingItr extends AbstractItr {
- @Override
- Node<E> firstNode() { return last; }
- @Override
- Node<E> nextNode(final Node<E> n) { return n.prev; }
- }
-
- /**
- * Saves the state of this deque to a stream (that is, serialize it).
- *
- * @serialData The capacity (int), followed by elements (each an
- * {@code Object}) in the proper order, followed by a null
- * @param s the stream
- */
- private void writeObject(final java.io.ObjectOutputStream s)
- throws java.io.IOException {
+ @Override
+ public String toString() {
lock.lock();
try {
- // Write out capacity and any hidden stuff
- s.defaultWriteObject();
- // Write out all elements in the proper order.
- for (Node<E> p = first; p != null; p = p.next) {
- s.writeObject(p.item);
- }
- // Use trailing null as sentinel
- s.writeObject(null);
+ return super.toString();
} finally {
lock.unlock();
}
}
/**
- * Reconstitutes this deque from a stream (that is,
- * deserialize it).
- * @param s the stream
+ * Unlinks the provided node.
+ *
+ * @param x The node to unlink
*/
- private void readObject(final java.io.ObjectInputStream s)
- throws java.io.IOException, ClassNotFoundException {
- s.defaultReadObject();
- count = 0;
- first = null;
- last = null;
- // Read in all elements and place in queue
- for (;;) {
- @SuppressWarnings("unchecked")
- final
- E item = (E)s.readObject();
- if (item == null) {
- break;
- }
- add(item);
+ private void unlink(final Node<E> x) {
+ // assert lock.isHeldByCurrentThread();
+ final Node<E> p = x.prev;
+ final Node<E> n = x.next;
+ if (p == null) {
+ unlinkFirst();
+ } else if (n == null) {
+ unlinkLast();
+ } else {
+ p.next = n;
+ n.prev = p;
+ x.item = null;
+ // Don't mess with x's links. They may still be in use by
+ // an iterator.
+ --count;
+ notFull.signal();
}
}
// Monitoring methods
/**
- * Returns true if there are threads waiting to take instances from this deque. See disclaimer on accuracy in
- * {@link java.util.concurrent.locks.ReentrantLock#hasWaiters(Condition)}.
+ * Removes and returns the first element, or null if empty.
*
- * @return true if there is at least one thread waiting on this deque's notEmpty condition.
+ * @return The first element or {@code null} if empty
*/
- public boolean hasTakeWaiters() {
- lock.lock();
- try {
- return lock.hasWaiters(notEmpty);
- } finally {
- lock.unlock();
+ private E unlinkFirst() {
+ // assert lock.isHeldByCurrentThread();
+ final Node<E> f = first;
+ if (f == null) {
+ return null;
}
+ final Node<E> n = f.next;
+ final E item = f.item;
+ f.item = null;
+ f.next = f; // help GC
+ first = n;
+ if (n == null) {
+ last = null;
+ } else {
+ n.prev = null;
+ }
+ --count;
+ notFull.signal();
+ return item;
}
/**
- * Returns the length of the queue of threads waiting to take instances from this deque. See disclaimer on accuracy
- * in {@link java.util.concurrent.locks.ReentrantLock#getWaitQueueLength(Condition)}.
+ * Removes and returns the last element, or null if empty.
*
- * @return number of threads waiting on this deque's notEmpty condition.
+ * @return The first element or {@code null} if empty
*/
- public int getTakeQueueLength() {
- lock.lock();
- try {
- return lock.getWaitQueueLength(notEmpty);
- } finally {
- lock.unlock();
+ private E unlinkLast() {
+ // assert lock.isHeldByCurrentThread();
+ final Node<E> l = last;
+ if (l == null) {
+ return null;
+ }
+ final Node<E> p = l.prev;
+ final E item = l.item;
+ l.item = null;
+ l.prev = l; // help GC
+ last = p;
+ if (p == null) {
+ first = null;
+ } else {
+ p.next = null;
}
+ --count;
+ notFull.signal();
+ return item;
}
/**
- * Interrupts the threads currently waiting to take an object from the pool. See disclaimer on accuracy in
- * {@link java.util.concurrent.locks.ReentrantLock#getWaitingThreads(Condition)}.
+ * Saves the state of this deque to a stream (that is, serialize it).
+ *
+ * @serialData The capacity (int), followed by elements (each an
+ * {@code Object}) in the proper order, followed by a null
+ * @param s the stream
*/
- public void interuptTakeWaiters() {
+ private void writeObject(final java.io.ObjectOutputStream s)
+ throws java.io.IOException {
lock.lock();
try {
- lock.interruptWaiters(notEmpty);
+ // Write out capacity and any hidden stuff
+ s.defaultWriteObject();
+ // Write out all elements in the proper order.
+ for (Node<E> p = first; p != null; p = p.next) {
+ s.writeObject(p.item);
+ }
+ // Use trailing null as sentinel
+ s.writeObject(null);
} finally {
lock.unlock();
}
diff --git a/src/main/java/org/apache/commons/pool2/impl/PoolImplUtils.java b/src/main/java/org/apache/commons/pool2/impl/PoolImplUtils.java
index 71ee1b7..6d6123e 100644
--- a/src/main/java/org/apache/commons/pool2/impl/PoolImplUtils.java
+++ b/src/main/java/org/apache/commons/pool2/impl/PoolImplUtils.java
@@ -19,6 +19,10 @@ package org.apache.commons.pool2.impl;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
+import java.time.Duration;
+import java.time.temporal.ChronoUnit;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
import org.apache.commons.pool2.PooledObjectFactory;
@@ -61,7 +65,7 @@ class PoolImplUtils {
}
return (Class<?>) genericType;
}
-
+
/**
* Obtains the concrete type used by an implementation of an interface that uses a generic type.
*
@@ -104,7 +108,7 @@ class PoolImplUtils {
return null;
}
}
-
+
/**
* Gets the matching parameterized type or null.
* @param type
@@ -153,4 +157,43 @@ class PoolImplUtils {
}
return null;
}
+
+ /**
+ * Converts a {@link TimeUnit} to a {@link ChronoUnit}.
+ *
+ * @param timeUnit A TimeUnit.
+ * @return The corresponding ChronoUnit.
+ */
+ static ChronoUnit toChronoUnit(TimeUnit timeUnit) {
+ // TODO when using Java >= 9: Use TimeUnit.toChronoUnit().
+ switch (Objects.requireNonNull(timeUnit)) {
+ case NANOSECONDS:
+ return ChronoUnit.NANOS;
+ case MICROSECONDS:
+ return ChronoUnit.MICROS;
+ case MILLISECONDS:
+ return ChronoUnit.MILLIS;
+ case SECONDS:
+ return ChronoUnit.SECONDS;
+ case MINUTES:
+ return ChronoUnit.MINUTES;
+ case HOURS:
+ return ChronoUnit.HOURS;
+ case DAYS:
+ return ChronoUnit.DAYS;
+ default:
+ throw new IllegalArgumentException(timeUnit.toString());
+ }
+ }
+
+ /**
+ * Converts am amount and TimeUnit into a Duration.
+ *
+ * @param amount the amount of the duration, measured in terms of the unit, positive or negative
+ * @param timeUnit the unit that the duration is measured in, must have an exact duration, not null
+ * @return a Duration.
+ */
+ static Duration toDuration(long amount, TimeUnit timeUnit) {
+ return Duration.of(amount, PoolImplUtils.toChronoUnit(timeUnit));
+ }
}
diff --git a/src/test/java/org/apache/commons/pool2/ObjectPoolIssue326.java b/src/test/java/org/apache/commons/pool2/ObjectPoolIssue326.java
index 95ed195..db2c2ce 100644
--- a/src/test/java/org/apache/commons/pool2/ObjectPoolIssue326.java
+++ b/src/test/java/org/apache/commons/pool2/ObjectPoolIssue326.java
@@ -17,6 +17,7 @@
package org.apache.commons.pool2;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
@@ -54,14 +55,14 @@ public final class ObjectPoolIssue326 {
poolConfig.setLifo(true);
poolConfig.setFairness(true);
poolConfig.setMaxWaitMillis(30 * 1000);
- poolConfig.setMinEvictableIdleTimeMillis(-1);
- poolConfig.setSoftMinEvictableIdleTimeMillis(-1);
+ poolConfig.setMinEvictableIdleTime(Duration.ofMillis(-1));
+ poolConfig.setSoftMinEvictableIdleTime(Duration.ofMillis(-1));
poolConfig.setNumTestsPerEvictionRun(1);
poolConfig.setTestOnCreate(false);
poolConfig.setTestOnBorrow(false);
poolConfig.setTestOnReturn(false);
poolConfig.setTestWhileIdle(false);
- poolConfig.setTimeBetweenEvictionRunsMillis(5 * 1000);
+ poolConfig.setTimeBetweenEvictionRuns(Duration.ofSeconds(5));
poolConfig.setEvictionPolicyClassName(BaseObjectPoolConfig.DEFAULT_EVICTION_POLICY_CLASS_NAME);
poolConfig.setBlockWhenExhausted(false);
poolConfig.setJmxEnabled(false);
diff --git a/src/test/java/org/apache/commons/pool2/PoolTest.java b/src/test/java/org/apache/commons/pool2/PoolTest.java
index 3fedd39..b115407 100644
--- a/src/test/java/org/apache/commons/pool2/PoolTest.java
+++ b/src/test/java/org/apache/commons/pool2/PoolTest.java
@@ -24,8 +24,11 @@ import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import java.time.Duration;
+
@Disabled
public class PoolTest {
private static final CharSequence COMMONS_POOL_EVICTIONS_TIMER_THREAD_NAME = "commons-pool-EvictionTimer";
@@ -72,6 +75,9 @@ public class PoolTest {
final PooledFooFactory pooledFooFactory = new PooledFooFactory();
try (GenericObjectPool<Foo> pool = new GenericObjectPool<>(pooledFooFactory, poolConfig)) {
pool.setTimeBetweenEvictionRunsMillis(EVICTION_PERIOD_IN_MILLIS);
+ assertEquals(EVICTION_PERIOD_IN_MILLIS, pool.getTimeBetweenEvictionRuns().toMillis());
+ pool.setTimeBetweenEvictionRuns(Duration.ofMillis(EVICTION_PERIOD_IN_MILLIS));
+ assertEquals(EVICTION_PERIOD_IN_MILLIS, pool.getTimeBetweenEvictionRuns().toMillis());
pool.addObject();
try {
Thread.sleep(EVICTION_PERIOD_IN_MILLIS);
diff --git a/src/test/java/org/apache/commons/pool2/impl/TestAbandonedObjectPool.java b/src/test/java/org/apache/commons/pool2/impl/TestAbandonedObjectPool.java
index 030f4e8..2013ca4 100644
--- a/src/test/java/org/apache/commons/pool2/impl/TestAbandonedObjectPool.java
+++ b/src/test/java/org/apache/commons/pool2/impl/TestAbandonedObjectPool.java
@@ -17,10 +17,15 @@
package org.apache.commons.pool2.impl;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.lang.management.ManagementFactory;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Set;
@@ -37,10 +42,6 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
/**
* TestCase for AbandonedObjectPool
*/
@@ -199,7 +200,7 @@ public class TestAbandonedObjectPool {
final int n = 10;
pool.setMaxTotal(n);
pool.setBlockWhenExhausted(false);
- pool.setTimeBetweenEvictionRunsMillis(500);
+ pool.setTimeBetweenEvictionRuns(Duration.ofMillis(500));
PooledTestObject obj = null;
for (int i = 0; i < 5; i++) {
obj = pool.borrowObject();
@@ -220,7 +221,7 @@ public class TestAbandonedObjectPool {
// validate takes 1 second
new SimpleFactory(0, 0),
new GenericObjectPoolConfig<PooledTestObject>(), abandonedConfig);
- pool.setTimeBetweenEvictionRunsMillis(50);
+ pool.setTimeBetweenEvictionRuns(Duration.ofMillis(50));
// Borrow an object, wait long enough for it to be abandoned
final PooledTestObject obj = pool.borrowObject();
Thread.sleep(100);
@@ -257,7 +258,7 @@ public class TestAbandonedObjectPool {
final int n = 10;
pool.setMaxTotal(n);
pool.setBlockWhenExhausted(false);
- pool.setTimeBetweenEvictionRunsMillis(500);
+ pool.setTimeBetweenEvictionRuns(Duration.ofMillis(500));
pool.setTestOnReturn(true);
// Borrow an object, wait long enough for it to be abandoned
// then arrange for evictor to run while it is being returned
@@ -283,7 +284,7 @@ public class TestAbandonedObjectPool {
public void testWhenExhaustedBlock() throws Exception {
abandonedConfig.setRemoveAbandonedOnMaintenance(true);
pool.setAbandonedConfig(abandonedConfig);
- pool.setTimeBetweenEvictionRunsMillis(500);
+ pool.setTimeBetweenEvictionRuns(Duration.ofMillis(500));
pool.setMaxTotal(1);
@@ -312,7 +313,7 @@ public class TestAbandonedObjectPool {
final PrintWriter pw = new PrintWriter(bos);
abandonedConfig.setLogWriter(pw);
pool.setAbandonedConfig(abandonedConfig);
- pool.setTimeBetweenEvictionRunsMillis(100);
+ pool.setTimeBetweenEvictionRuns(Duration.ofMillis(100));
final PooledTestObject o1 = pool.borrowObject();
Thread.sleep(2000);
assertTrue(o1.isDestroyed());
diff --git a/src/test/java/org/apache/commons/pool2/impl/TestBaseGenericObjectPool.java b/src/test/java/org/apache/commons/pool2/impl/TestBaseGenericObjectPool.java
index a24e02f..2007e0c 100644
--- a/src/test/java/org/apache/commons/pool2/impl/TestBaseGenericObjectPool.java
+++ b/src/test/java/org/apache/commons/pool2/impl/TestBaseGenericObjectPool.java
@@ -17,6 +17,9 @@
package org.apache.commons.pool2.impl;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.time.Duration;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.pool2.impl.TestGenericObjectPool.SimpleFactory;
@@ -24,8 +27,6 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
/**
*/
public class TestBaseGenericObjectPool {
@@ -83,10 +84,10 @@ public class TestBaseGenericObjectPool {
final AtomicIntegerFactory factory = new AtomicIntegerFactory();
factory.setValidateLatency(50);
try (final GenericObjectPool<AtomicInteger> evictingPool = new GenericObjectPool<>(factory)) {
- evictingPool.setTimeBetweenEvictionRunsMillis(100);
+ evictingPool.setTimeBetweenEvictionRuns(Duration.ofMillis(100));
evictingPool.setNumTestsPerEvictionRun(5);
evictingPool.setTestWhileIdle(true);
- evictingPool.setMinEvictableIdleTimeMillis(50);
+ evictingPool.setMinEvictableIdleTime(Duration.ofMillis(50));
for (int i = 0; i < 10; i++) {
try {
evictingPool.addObject();
diff --git a/src/test/java/org/apache/commons/pool2/impl/TestConstants.java b/src/test/java/org/apache/commons/pool2/impl/TestConstants.java
index 1eeb967..59479ad 100644
--- a/src/test/java/org/apache/commons/pool2/impl/TestConstants.java
+++ b/src/test/java/org/apache/commons/pool2/impl/TestConstants.java
@@ -23,5 +23,6 @@ public class TestConstants {
public static final Duration ONE_SECOND = Duration.ofSeconds(1);
public static final Duration ONE_MINUTE = Duration.ofMinutes(1);
+ public static final Duration ONE_MILLISECOND = Duration.ofMillis(1);
}
diff --git a/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java b/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java
index ed8faf2..74aed0e 100644
--- a/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java
+++ b/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java
@@ -18,9 +18,19 @@
package org.apache.commons.pool2.impl;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.management.ManagementFactory;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.NoSuchElementException;
@@ -55,15 +65,6 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNotSame;
-import static org.junit.jupiter.api.Assertions.assertSame;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
-
/**
*/
public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
@@ -388,23 +389,27 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
public void testSettersAndGetters() throws Exception {
{
gkoPool.setMaxTotalPerKey(123);
- assertEquals(123,gkoPool.getMaxTotalPerKey());
+ assertEquals(123, gkoPool.getMaxTotalPerKey());
}
{
gkoPool.setMaxIdlePerKey(12);
- assertEquals(12,gkoPool.getMaxIdlePerKey());
+ assertEquals(12, gkoPool.getMaxIdlePerKey());
}
{
gkoPool.setMaxWaitMillis(1234L);
- assertEquals(1234L,gkoPool.getMaxWaitMillis());
+ assertEquals(1234L, gkoPool.getMaxWaitMillis());
}
{
gkoPool.setMinEvictableIdleTimeMillis(12345L);
- assertEquals(12345L,gkoPool.getMinEvictableIdleTimeMillis());
+ assertEquals(12345L, gkoPool.getMinEvictableIdleTimeMillis());
+ }
+ {
+ gkoPool.setMinEvictableIdleTime(Duration.ofMillis(12345L));
+ assertEquals(12345L, gkoPool.getMinEvictableIdleTime().toMillis());
}
{
gkoPool.setNumTestsPerEvictionRun(11);
- assertEquals(11,gkoPool.getNumTestsPerEvictionRun());
+ assertEquals(11, gkoPool.getNumTestsPerEvictionRun());
}
{
gkoPool.setTestOnBorrow(true);
@@ -426,7 +431,11 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
}
{
gkoPool.setTimeBetweenEvictionRunsMillis(11235L);
- assertEquals(11235L,gkoPool.getTimeBetweenEvictionRunsMillis());
+ assertEquals(11235L, gkoPool.getTimeBetweenEvictionRunsMillis());
+ }
+ {
+ gkoPool.setTimeBetweenEvictionRuns(Duration.ofMillis(11235L));
+ assertEquals(11235L, gkoPool.getTimeBetweenEvictionRuns().toMillis());
}
{
gkoPool.setBlockWhenExhausted(true);
@@ -443,8 +452,8 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
@Test
public void testContructorEvictionConfig() throws Exception {
final GenericKeyedObjectPoolConfig<String> config = new GenericKeyedObjectPoolConfig<>();
- config.setTimeBetweenEvictionRunsMillis(500);
- config.setMinEvictableIdleTimeMillis(50);
+ config.setTimeBetweenEvictionRuns(Duration.ofMillis(500));
+ config.setMinEvictableIdleTime(Duration.ofMillis(50));
config.setNumTestsPerEvictionRun(5);
try (final GenericKeyedObjectPool<String, String> p = new GenericKeyedObjectPool<>(simpleFactory, config)) {
for (int i = 0; i < 5; i++) {
@@ -472,8 +481,8 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
gkoPool.setMaxIdlePerKey(500);
gkoPool.setMaxTotalPerKey(500);
gkoPool.setNumTestsPerEvictionRun(100);
- gkoPool.setMinEvictableIdleTimeMillis(250L);
- gkoPool.setTimeBetweenEvictionRunsMillis(500L);
+ gkoPool.setMinEvictableIdleTime(Duration.ofMillis(250));
+ gkoPool.setTimeBetweenEvictionRuns(Duration.ofMillis(500));
final String[] active = new String[500];
for(int i=0;i<500;i++) {
@@ -523,8 +532,8 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
gkoPool.setMaxIdlePerKey(500);
gkoPool.setMaxTotalPerKey(500);
gkoPool.setNumTestsPerEvictionRun(100);
- gkoPool.setMinEvictableIdleTimeMillis(500L);
- gkoPool.setTimeBetweenEvictionRunsMillis(500L);
+ gkoPool.setMinEvictableIdleTime(Duration.ofMillis(500));
+ gkoPool.setTimeBetweenEvictionRuns(Duration.ofMillis(500));
final String[] active = new String[500];
final String[] active2 = new String[500];
@@ -678,8 +687,8 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
gkoPool.setMinIdlePerKey(5);
gkoPool.setMaxTotalPerKey(10);
gkoPool.setNumTestsPerEvictionRun(0);
- gkoPool.setMinEvictableIdleTimeMillis(50L);
- gkoPool.setTimeBetweenEvictionRunsMillis(100L);
+ gkoPool.setMinEvictableIdleTime(Duration.ofMillis(50));
+ gkoPool.setTimeBetweenEvictionRuns(Duration.ofMillis(100));
gkoPool.setTestWhileIdle(true);
@@ -719,8 +728,8 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
gkoPool.setMinIdlePerKey(5);
gkoPool.setMaxTotalPerKey(10);
gkoPool.setNumTestsPerEvictionRun(0);
- gkoPool.setMinEvictableIdleTimeMillis(50L);
- gkoPool.setTimeBetweenEvictionRunsMillis(100L);
+ gkoPool.setMinEvictableIdleTime(Duration.ofMillis(50));
+ gkoPool.setTimeBetweenEvictionRuns(Duration.ofMillis(100));
gkoPool.setTestWhileIdle(true);
final String key = "A";
@@ -773,8 +782,8 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
gkoPool.setMinIdlePerKey(5);
gkoPool.setMaxTotalPerKey(10);
gkoPool.setNumTestsPerEvictionRun(0);
- gkoPool.setMinEvictableIdleTimeMillis(50L);
- gkoPool.setTimeBetweenEvictionRunsMillis(100L);
+ gkoPool.setMinEvictableIdleTime(Duration.ofMillis(50));
+ gkoPool.setTimeBetweenEvictionRuns(Duration.ofMillis(100));
gkoPool.setTestWhileIdle(true);
@@ -846,7 +855,7 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
final SimpleFactory<Integer> intFactory = new SimpleFactory<>();
try (final GenericKeyedObjectPool<Integer, String> intPool = new GenericKeyedObjectPool<>(intFactory)) {
intPool.setNumTestsPerEvictionRun(2);
- intPool.setMinEvictableIdleTimeMillis(100);
+ intPool.setMinEvictableIdleTime(Duration.ofMillis(100));
intPool.setLifo(lifo);
for (int i = 0; i < 3; i++) {
@@ -906,7 +915,7 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
intPool.clear();
// Reload
- intPool.setMinEvictableIdleTimeMillis(500);
+ intPool.setMinEvictableIdleTime(Duration.ofMillis(500));
intFactory.counter = 0; // Reset counter
for (int i = 0; i < 3; i++) {
final Integer key = Integer.valueOf(i);
@@ -972,7 +981,7 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
try (GenericKeyedObjectPool<Integer, VisitTracker<Integer>> intPool = new GenericKeyedObjectPool<>(
trackerFactory)) {
intPool.setNumTestsPerEvictionRun(2);
- intPool.setMinEvictableIdleTimeMillis(-1);
+ intPool.setMinEvictableIdleTime(Duration.ofMillis(-1));
intPool.setTestWhileIdle(true);
intPool.setLifo(lifo);
intPool.setTestOnReturn(false);
@@ -1058,7 +1067,7 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
intPool.setMaxIdlePerKey(-1);
intPool.setMaxTotalPerKey(-1);
intPool.setNumTestsPerEvictionRun(smallPrimes[i]);
- intPool.setMinEvictableIdleTimeMillis(-1);
+ intPool.setMinEvictableIdleTime(Duration.ofMillis(-1));
intPool.setTestWhileIdle(true);
intPool.setLifo(lifo);
intPool.setTestOnReturn(false);
@@ -1194,6 +1203,7 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
}
}
+ @SuppressWarnings("deprecation")
@Test
@Timeout(value = 60000, unit = TimeUnit.MILLISECONDS)
public void testConstructors() throws Exception {
@@ -1220,8 +1230,12 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
assertEquals(BaseObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS, objPool.getMaxWaitMillis());
assertEquals(GenericKeyedObjectPoolConfig.DEFAULT_MIN_IDLE_PER_KEY, objPool.getMinIdlePerKey());
assertEquals(GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL, objPool.getMaxTotal());
+ //
assertEquals(BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,
objPool.getMinEvictableIdleTimeMillis());
+ assertEquals(BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME,
+ objPool.getMinEvictableIdleTime());
+ //
assertEquals(BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN, objPool.getNumTestsPerEvictionRun());
assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_TEST_ON_BORROW),
Boolean.valueOf(objPool.getTestOnBorrow()));
@@ -1229,8 +1243,12 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
Boolean.valueOf(objPool.getTestOnReturn()));
assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_TEST_WHILE_IDLE),
Boolean.valueOf(objPool.getTestWhileIdle()));
+ //
assertEquals(BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
objPool.getTimeBetweenEvictionRunsMillis());
+ assertEquals(BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS,
+ objPool.getTimeBetweenEvictionRuns());
+ //
assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED),
Boolean.valueOf(objPool.getBlockWhenExhausted()));
assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_LIFO), Boolean.valueOf(objPool.getLifo()));
@@ -1243,12 +1261,12 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
config.setMinIdlePerKey(minIdle);
config.setMaxTotal(maxTotal);
config.setMaxWaitMillis(maxWait);
- config.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+ config.setMinEvictableIdleTime(Duration.ofMillis(minEvictableIdleTimeMillis));
config.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
config.setTestOnBorrow(testOnBorrow);
config.setTestOnReturn(testOnReturn);
config.setTestWhileIdle(testWhileIdle);
- config.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+ config.setTimeBetweenEvictionRuns(Duration.ofMillis(timeBetweenEvictionRunsMillis));
config.setBlockWhenExhausted(blockWhenExhausted);
try (GenericKeyedObjectPool<Object, Object> objPool = new GenericKeyedObjectPool<>(dummyFactory, config)) {
assertEquals(maxTotalPerKey, objPool.getMaxTotalPerKey());
@@ -1257,11 +1275,13 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
assertEquals(minIdle, objPool.getMinIdlePerKey());
assertEquals(maxTotal, objPool.getMaxTotal());
assertEquals(minEvictableIdleTimeMillis, objPool.getMinEvictableIdleTimeMillis());
+ assertEquals(minEvictableIdleTimeMillis, objPool.getMinEvictableIdleTime().toMillis());
assertEquals(numTestsPerEvictionRun, objPool.getNumTestsPerEvictionRun());
assertEquals(Boolean.valueOf(testOnBorrow), Boolean.valueOf(objPool.getTestOnBorrow()));
assertEquals(Boolean.valueOf(testOnReturn), Boolean.valueOf(objPool.getTestOnReturn()));
assertEquals(Boolean.valueOf(testWhileIdle), Boolean.valueOf(objPool.getTestWhileIdle()));
assertEquals(timeBetweenEvictionRunsMillis, objPool.getTimeBetweenEvictionRunsMillis());
+ assertEquals(timeBetweenEvictionRunsMillis, objPool.getTimeBetweenEvictionRuns().toMillis());
assertEquals(Boolean.valueOf(blockWhenExhausted), Boolean.valueOf(objPool.getBlockWhenExhausted()));
assertEquals(Boolean.valueOf(lifo), Boolean.valueOf(objPool.getLifo()));
}
@@ -2073,7 +2093,7 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
config.setTestOnBorrow(true);
config.setTestOnReturn(false);
config.setTestWhileIdle(true);
- config.setTimeBetweenEvictionRunsMillis(-1);
+ config.setTimeBetweenEvictionRuns(Duration.ofMillis(-1));
try (final GenericKeyedObjectPool<Integer, Object> pool = new GenericKeyedObjectPool<>(new ObjectFactory(),
config)) {
@@ -2233,7 +2253,7 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
pool.setTestWhileIdle(true);
pool.setMaxTotalPerKey(2);
pool.setNumTestsPerEvictionRun(1);
- pool.setTimeBetweenEvictionRunsMillis(500);
+ pool.setTimeBetweenEvictionRuns(Duration.ofMillis(500));
// Load pool with two objects
pool.addObject("one"); // call this o1
@@ -2391,7 +2411,7 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
// POOL-326
@Test
public void testEvictorClearOldestRace() throws Exception {
- gkoPool.setMinEvictableIdleTimeMillis(100);
+ gkoPool.setMinEvictableIdleTime(Duration.ofMillis(100));
gkoPool.setNumTestsPerEvictionRun(1);
// Introduce latency between when evictor starts looking at an instance and when
@@ -2408,7 +2428,7 @@ public class TestGenericKeyedObjectPool extends TestKeyedObjectPool {
Thread.sleep(1000);
// Start evictor and race with clearOldest
- gkoPool.setTimeBetweenEvictionRunsMillis(10);
+ gkoPool.setTimeBetweenEvictionRuns(Duration.ofMillis(10));
// Wait for evictor to start
Thread.sleep(100);
diff --git a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java
index 61f14ba..747faa2 100644
--- a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java
+++ b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java
@@ -595,29 +595,41 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
private SimpleFactory simpleFactory = null;
- private void assertConfiguration(final GenericObjectPoolConfig<?> expected, final GenericObjectPool<?> actual) throws Exception {
- assertEquals(Boolean.valueOf(expected.getTestOnCreate()),
- Boolean.valueOf(actual.getTestOnCreate()),"testOnCreate");
- assertEquals(Boolean.valueOf(expected.getTestOnBorrow()),
- Boolean.valueOf(actual.getTestOnBorrow()),"testOnBorrow");
- assertEquals(Boolean.valueOf(expected.getTestOnReturn()),
- Boolean.valueOf(actual.getTestOnReturn()),"testOnReturn");
- assertEquals(Boolean.valueOf(expected.getTestWhileIdle()),
- Boolean.valueOf(actual.getTestWhileIdle()),"testWhileIdle");
- assertEquals(Boolean.valueOf(expected.getBlockWhenExhausted()),
- Boolean.valueOf(actual.getBlockWhenExhausted()),"whenExhaustedAction");
- assertEquals(expected.getMaxTotal(),actual.getMaxTotal(),"maxTotal");
- assertEquals(expected.getMaxIdle(),actual.getMaxIdle(),"maxIdle");
- assertEquals(expected.getMaxWaitMillis(),actual.getMaxWaitMillis(),"maxWait");
- assertEquals(expected.getMinEvictableIdleTimeMillis(),actual.getMinEvictableIdleTimeMillis(),"minEvictableIdleTimeMillis");
- assertEquals(expected.getNumTestsPerEvictionRun(),actual.getNumTestsPerEvictionRun(),"numTestsPerEvictionRun");
- assertEquals(expected.getEvictorShutdownTimeoutMillis(),actual.getEvictorShutdownTimeoutMillis(),"evictorShutdownTimeoutMillis");
- assertEquals(expected.getTimeBetweenEvictionRunsMillis(),actual.getTimeBetweenEvictionRunsMillis(),"timeBetweenEvictionRunsMillis");
+ @SuppressWarnings("deprecation")
+ private void assertConfiguration(final GenericObjectPoolConfig<?> expected, final GenericObjectPool<?> actual)
+ throws Exception {
+ assertEquals(Boolean.valueOf(expected.getTestOnCreate()), Boolean.valueOf(actual.getTestOnCreate()),
+ "testOnCreate");
+ assertEquals(Boolean.valueOf(expected.getTestOnBorrow()), Boolean.valueOf(actual.getTestOnBorrow()),
+ "testOnBorrow");
+ assertEquals(Boolean.valueOf(expected.getTestOnReturn()), Boolean.valueOf(actual.getTestOnReturn()),
+ "testOnReturn");
+ assertEquals(Boolean.valueOf(expected.getTestWhileIdle()), Boolean.valueOf(actual.getTestWhileIdle()),
+ "testWhileIdle");
+ assertEquals(Boolean.valueOf(expected.getBlockWhenExhausted()), Boolean.valueOf(actual.getBlockWhenExhausted()),
+ "whenExhaustedAction");
+ assertEquals(expected.getMaxTotal(), actual.getMaxTotal(), "maxTotal");
+ assertEquals(expected.getMaxIdle(), actual.getMaxIdle(), "maxIdle");
+ assertEquals(expected.getMaxWaitMillis(), actual.getMaxWaitMillis(), "maxWait");
+ assertEquals(expected.getMinEvictableIdleTimeMillis(), actual.getMinEvictableIdleTimeMillis(),
+ "minEvictableIdleTimeMillis");
+ assertEquals(expected.getMinEvictableIdleTime(), actual.getMinEvictableIdleTime(),
+ "minEvictableIdleTime");
+ assertEquals(expected.getNumTestsPerEvictionRun(), actual.getNumTestsPerEvictionRun(),
+ "numTestsPerEvictionRun");
+ assertEquals(expected.getEvictorShutdownTimeoutMillis(), actual.getEvictorShutdownTimeoutMillis(),
+ "evictorShutdownTimeoutMillis");
+ assertEquals(expected.getEvictorShutdownTimeout(), actual.getEvictorShutdownTimeout(),
+ "evictorShutdownTimeout");
+ assertEquals(expected.getTimeBetweenEvictionRunsMillis(), actual.getTimeBetweenEvictionRunsMillis(),
+ "timeBetweenEvictionRunsMillis");
+ assertEquals(expected.getTimeBetweenEvictionRuns(), actual.getTimeBetweenEvictionRuns(),
+ "timeBetweenEvictionRuns");
}
private void checkEvict(final boolean lifo) throws Exception {
// yea this is hairy but it tests all the code paths in GOP.evict()
- genericObjectPool.setSoftMinEvictableIdleTimeMillis(10);
+ genericObjectPool.setSoftMinEvictableIdleTime(Duration.ofMillis(10));
genericObjectPool.setMinIdle(2);
genericObjectPool.setTestWhileIdle(true);
genericObjectPool.setLifo(lifo);
@@ -648,7 +660,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
private void checkEvictionOrderPart1(final boolean lifo) throws Exception {
genericObjectPool.setNumTestsPerEvictionRun(2);
- genericObjectPool.setMinEvictableIdleTimeMillis(100);
+ genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(100));
genericObjectPool.setLifo(lifo);
for (int i = 0; i < 5; i++) {
genericObjectPool.addObject();
@@ -666,7 +678,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
private void checkEvictionOrderPart2(final boolean lifo) throws Exception {
// Two eviction runs in sequence
genericObjectPool.setNumTestsPerEvictionRun(2);
- genericObjectPool.setMinEvictableIdleTimeMillis(100);
+ genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(100));
genericObjectPool.setLifo(lifo);
for (int i = 0; i < 5; i++) {
genericObjectPool.addObject();
@@ -683,7 +695,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
VisitTrackerFactory<Object> trackerFactory = new VisitTrackerFactory<>();
try (GenericObjectPool<VisitTracker<Object>> trackerPool = new GenericObjectPool<>(trackerFactory)) {
trackerPool.setNumTestsPerEvictionRun(2);
- trackerPool.setMinEvictableIdleTimeMillis(-1);
+ trackerPool.setMinEvictableIdleTime(Duration.ofMillis(-1));
trackerPool.setTestWhileIdle(true);
trackerPool.setLifo(lifo);
trackerPool.setTestOnReturn(false);
@@ -714,7 +726,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
trackerFactory = new VisitTrackerFactory<>();
try (GenericObjectPool<VisitTracker<Object>> trackerPool = new GenericObjectPool<>(trackerFactory)) {
trackerPool.setNumTestsPerEvictionRun(3);
- trackerPool.setMinEvictableIdleTimeMillis(-1);
+ trackerPool.setMinEvictableIdleTime(Duration.ofMillis(-1));
trackerPool.setTestWhileIdle(true);
trackerPool.setLifo(lifo);
trackerPool.setTestOnReturn(false);
@@ -757,7 +769,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
for (int j = 0; j < 5; j++) {
try (GenericObjectPool<VisitTracker<Object>> trackerPool = new GenericObjectPool<>(trackerFactory)) {
trackerPool.setNumTestsPerEvictionRun(smallPrimes[i]);
- trackerPool.setMinEvictableIdleTimeMillis(-1);
+ trackerPool.setMinEvictableIdleTime(Duration.ofMillis(-1));
trackerPool.setTestWhileIdle(true);
trackerPool.setLifo(lifo);
trackerPool.setTestOnReturn(false);
@@ -1090,8 +1102,8 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
@Timeout(value = 60000, unit = TimeUnit.MILLISECONDS)
public void testCloseMultiplePools1() throws Exception {
try (final GenericObjectPool<String> genericObjectPool2 = new GenericObjectPool<>(simpleFactory)) {
- genericObjectPool.setTimeBetweenEvictionRunsMillis(1);
- genericObjectPool2.setTimeBetweenEvictionRunsMillis(1);
+ genericObjectPool.setTimeBetweenEvictionRuns(TestConstants.ONE_MILLISECOND);
+ genericObjectPool2.setTimeBetweenEvictionRuns(TestConstants.ONE_MILLISECOND);
}
genericObjectPool.close();
}
@@ -1103,10 +1115,10 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
// Ensure eviction takes a long time, during which time EvictionTimer.executor's queue is empty
simpleFactory.setDestroyLatency(1000L);
// Ensure there is an object to evict, so that above latency takes effect
- genericObjectPool.setTimeBetweenEvictionRunsMillis(1);
- genericObjectPool2.setTimeBetweenEvictionRunsMillis(1);
- genericObjectPool.setMinEvictableIdleTimeMillis(1);
- genericObjectPool2.setMinEvictableIdleTimeMillis(1);
+ genericObjectPool.setTimeBetweenEvictionRuns(TestConstants.ONE_MILLISECOND);
+ genericObjectPool2.setTimeBetweenEvictionRuns(TestConstants.ONE_MILLISECOND);
+ genericObjectPool.setMinEvictableIdleTime(TestConstants.ONE_MILLISECOND);
+ genericObjectPool2.setMinEvictableIdleTime(TestConstants.ONE_MILLISECOND);
genericObjectPool.addObject();
genericObjectPool2.addObject();
// Close both pools
@@ -1228,6 +1240,8 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
assertEquals(GenericObjectPoolConfig.DEFAULT_MAX_TOTAL, dummyPool.getMaxTotal());
assertEquals(BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,
dummyPool.getMinEvictableIdleTimeMillis());
+ assertEquals(BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME,
+ dummyPool.getMinEvictableIdleTime());
assertEquals(BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
dummyPool.getNumTestsPerEvictionRun());
assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_TEST_ON_BORROW),
@@ -1238,6 +1252,8 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
Boolean.valueOf(dummyPool.getTestWhileIdle()));
assertEquals(BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
dummyPool.getTimeBetweenEvictionRunsMillis());
+ assertEquals(BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS,
+ dummyPool.getTimeBetweenEvictionRuns());
assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED),
Boolean.valueOf(dummyPool.getBlockWhenExhausted()));
assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_LIFO), Boolean.valueOf(dummyPool.getLifo()));
@@ -1250,11 +1266,13 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
config.setMaxTotal(maxTotal);
config.setMaxWaitMillis(maxWait);
config.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+ assertEquals(minEvictableIdleTimeMillis, config.getMinEvictableIdleTime().toMillis());
config.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
config.setTestOnBorrow(testOnBorrow);
config.setTestOnReturn(testOnReturn);
config.setTestWhileIdle(testWhileIdle);
config.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+ assertEquals(timeBetweenEvictionRunsMillis, config.getTimeBetweenEvictionRuns().toMillis());
config.setBlockWhenExhausted(blockWhenExhausted);
try (GenericObjectPool<Object> dummyPool = new GenericObjectPool<>(dummyFactory, config)) {
assertEquals(maxIdle, dummyPool.getMaxIdle());
@@ -1364,7 +1382,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
final TestThread<String> borrower = new TestThread<>(genericObjectPool, 1, 150, false);
final Thread borrowerThread = new Thread(borrower);
// Set evictor to run in 100 ms - will create idle instance
- genericObjectPool.setTimeBetweenEvictionRunsMillis(100);
+ genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(100));
borrowerThread.start(); // Off to the races
borrowerThread.join();
assertTrue(!borrower.failed());
@@ -1382,8 +1400,8 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
genericObjectPool.setMaxIdle(500);
genericObjectPool.setMaxTotal(500);
genericObjectPool.setNumTestsPerEvictionRun(100);
- genericObjectPool.setMinEvictableIdleTimeMillis(250L);
- genericObjectPool.setTimeBetweenEvictionRunsMillis(500L);
+ genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(250));
+ genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(500));
genericObjectPool.setTestWhileIdle(true);
final String[] active = new String[500];
@@ -1439,7 +1457,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
invalidFactoryPool.setTestOnBorrow(false);
invalidFactoryPool.setTestOnReturn(false);
invalidFactoryPool.setTestWhileIdle(true);
- invalidFactoryPool.setMinEvictableIdleTimeMillis(100000);
+ invalidFactoryPool.setMinEvictableIdleTime(Duration.ofSeconds(100));
invalidFactoryPool.setNumTestsPerEvictionRun(1);
final Object p = invalidFactoryPool.borrowObject();
@@ -1490,8 +1508,8 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
genericObjectPool.setMaxIdle(500);
genericObjectPool.setMaxTotal(500);
genericObjectPool.setNumTestsPerEvictionRun(500);
- genericObjectPool.setMinEvictableIdleTimeMillis(250L);
- genericObjectPool.setTimeBetweenEvictionRunsMillis(500L);
+ genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(250));
+ genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(500));
genericObjectPool.setTestWhileIdle(true);
// ClassNotFoundException
@@ -1581,8 +1599,8 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
timePool.setMaxIdle(5);
timePool.setMaxTotal(5);
timePool.setNumTestsPerEvictionRun(5);
- timePool.setMinEvictableIdleTimeMillis(3000L);
- timePool.setSoftMinEvictableIdleTimeMillis(1000L);
+ timePool.setMinEvictableIdleTime(Duration.ofSeconds(3));
+ timePool.setSoftMinEvictableIdleTime(TestConstants.ONE_SECOND);
timePool.setMinIdle(2);
final TimeTest[] active = new TimeTest[5];
@@ -1615,8 +1633,8 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
genericObjectPool.setMaxIdle(6);
genericObjectPool.setMaxTotal(6);
genericObjectPool.setNumTestsPerEvictionRun(-2);
- genericObjectPool.setMinEvictableIdleTimeMillis(50L);
- genericObjectPool.setTimeBetweenEvictionRunsMillis(100L);
+ genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(50));
+ genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(100));
final String[] active = new String[6];
for (int i = 0; i < 6; i++) {
@@ -1997,7 +2015,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
simpleFactory.setMaxTotal(maxTotal);
genericObjectPool.setMaxTotal(maxTotal);
genericObjectPool.setBlockWhenExhausted(true);
- genericObjectPool.setTimeBetweenEvictionRunsMillis(-1);
+ genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(-1));
// this is important to trigger POOL-356
genericObjectPool.setMaxIdle(0);
@@ -2141,7 +2159,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
simpleFactory.setMaxTotal(maxTotal);
genericObjectPool.setMaxTotal(maxTotal);
genericObjectPool.setBlockWhenExhausted(true);
- genericObjectPool.setTimeBetweenEvictionRunsMillis(-1);
+ genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(-1));
// Start threads to borrow objects
final TestThread[] threads = new TestThread[numThreads];
@@ -2283,8 +2301,8 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
genericObjectPool.setMinIdle(5);
genericObjectPool.setMaxTotal(10);
genericObjectPool.setNumTestsPerEvictionRun(0);
- genericObjectPool.setMinEvictableIdleTimeMillis(50L);
- genericObjectPool.setTimeBetweenEvictionRunsMillis(100L);
+ genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(50));
+ genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(100));
genericObjectPool.setTestWhileIdle(true);
try { Thread.sleep(150L); } catch(final InterruptedException e) { }
@@ -2318,8 +2336,8 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
genericObjectPool.setMinIdle(5);
genericObjectPool.setMaxTotal(10);
genericObjectPool.setNumTestsPerEvictionRun(0);
- genericObjectPool.setMinEvictableIdleTimeMillis(50L);
- genericObjectPool.setTimeBetweenEvictionRunsMillis(100L);
+ genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(50));
+ genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(100));
genericObjectPool.setTestWhileIdle(true);
try { Thread.sleep(150L); } catch(final InterruptedException e) { }
@@ -2552,13 +2570,13 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
expected.setMaxTotal(2);
expected.setMaxIdle(3);
expected.setMaxWaitMillis(5L);
- expected.setMinEvictableIdleTimeMillis(7L);
+ expected.setMinEvictableIdleTime(Duration.ofMillis(7L));
expected.setNumTestsPerEvictionRun(9);
expected.setTestOnCreate(true);
expected.setTestOnBorrow(true);
expected.setTestOnReturn(true);
expected.setTestWhileIdle(true);
- expected.setTimeBetweenEvictionRunsMillis(11L);
+ expected.setTimeBetweenEvictionRuns(Duration.ofMillis(11L));
expected.setBlockWhenExhausted(false);
genericObjectPool.setConfig(expected);
assertConfiguration(expected,genericObjectPool);
@@ -2620,6 +2638,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
{
genericObjectPool.setMinEvictableIdleTimeMillis(12345L);
assertEquals(12345L,genericObjectPool.getMinEvictableIdleTimeMillis());
+ assertEquals(12345L,genericObjectPool.getMinEvictableIdleTime().toMillis());
}
{
genericObjectPool.setNumTestsPerEvictionRun(11);
@@ -2646,10 +2665,12 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
{
genericObjectPool.setTimeBetweenEvictionRunsMillis(11235L);
assertEquals(11235L,genericObjectPool.getTimeBetweenEvictionRunsMillis());
+ assertEquals(11235L,genericObjectPool.getTimeBetweenEvictionRuns().toMillis());
}
{
genericObjectPool.setSoftMinEvictableIdleTimeMillis(12135L);
assertEquals(12135L,genericObjectPool.getSoftMinEvictableIdleTimeMillis());
+ assertEquals(12135L,genericObjectPool.getSoftMinEvictableIdleTime().toMillis());
}
{
genericObjectPool.setBlockWhenExhausted(true);
@@ -2666,7 +2687,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
genericObjectPool.setMaxIdle(6);
genericObjectPool.setMaxTotal(6);
genericObjectPool.setNumTestsPerEvictionRun(6);
- genericObjectPool.setMinEvictableIdleTimeMillis(100L);
+ genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(100));
for (int j = 0; j < 2; j++) {
// populate the pool
@@ -2684,7 +2705,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
assertEquals(6,genericObjectPool.getNumIdle(),"Should have 6 idle");
// start the evictor
- genericObjectPool.setTimeBetweenEvictionRunsMillis(50L);
+ genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(50));
// wait a second (well, .2 seconds)
try { Thread.sleep(200L); } catch(final InterruptedException e) { }
@@ -2968,7 +2989,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool {
final GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setJmxEnabled(false);
GenericObjectPool<String> abandoned = new GenericObjectPool<>(simpleFactory, config);
- abandoned.setTimeBetweenEvictionRunsMillis(100); // Starts evictor
+ abandoned.setTimeBetweenEvictionRuns(Duration.ofMillis(100)); // Starts evictor
assertEquals(abandoned.getRemoveAbandonedTimeout(), abandoned.getRemoveAbandonedTimeoutDuration().getSeconds());
// This is ugly, but forces gc to hit the pool
diff --git a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolClassLoaders.java b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolClassLoaders.java
index dd9bf22..b00d8d9 100644
--- a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolClassLoaders.java
+++ b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolClassLoaders.java
@@ -18,6 +18,7 @@ package org.apache.commons.pool2.impl;
import java.net.URL;
import java.net.URLClassLoader;
+import java.time.Duration;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
@@ -45,7 +46,7 @@ public class TestGenericObjectPoolClassLoaders {
new CustomClassLoaderObjectFactory(1);
final GenericObjectPool<URL> pool1 = new GenericObjectPool<>(factory1);
pool1.setMinIdle(1);
- pool1.setTimeBetweenEvictionRunsMillis(100);
+ pool1.setTimeBetweenEvictionRuns(Duration.ofMillis(100));
int counter = 0;
while (counter < 50 && pool1.getNumIdle() != 1) {
Thread.sleep(100);
@@ -66,7 +67,7 @@ public class TestGenericObjectPoolClassLoaders {
assertEquals( 1, pool2.getNumIdle(),"Wrong number of idle objects in pool2");
pool2.clear();
- pool2.setTimeBetweenEvictionRunsMillis(100);
+ pool2.setTimeBetweenEvictionRuns(Duration.ofMillis(100));
counter = 0;
while (counter < 50 && pool2.getNumIdle() != 1) {
diff --git a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolFactoryCreateFailure.java b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolFactoryCreateFailure.java
index eec7725..3d85b87 100644
--- a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolFactoryCreateFailure.java
+++ b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolFactoryCreateFailure.java
@@ -17,6 +17,7 @@
package org.apache.commons.pool2.impl;
+import java.time.Duration;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -111,9 +112,9 @@ public class TestGenericObjectPoolFactoryCreateFailure {
config.setTestOnBorrow(true);
config.setTestOnReturn(true);
config.setTestWhileIdle(false);
- config.setTimeBetweenEvictionRunsMillis(-1);
- config.setMinEvictableIdleTimeMillis(-1);
- config.setSoftMinEvictableIdleTimeMillis(-1);
+ config.setTimeBetweenEvictionRuns(Duration.ofMillis(-1));
+ config.setMinEvictableIdleTime(Duration.ofMillis(-1));
+ config.setSoftMinEvictableIdleTime(Duration.ofMillis(-1));
config.setMaxWaitMillis(-1);
try (GenericObjectPool<Object> pool = new GenericObjectPool<>(factory, config)) {
diff --git a/src/test/java/org/apache/commons/pool2/impl/TestLinkedBlockingDeque.java b/src/test/java/org/apache/commons/pool2/impl/TestLinkedBlockingDeque.java
index 3c0e236..edcb360 100644
--- a/src/test/java/org/apache/commons/pool2/impl/TestLinkedBlockingDeque.java
+++ b/src/test/java/org/apache/commons/pool2/impl/TestLinkedBlockingDeque.java
@@ -21,6 +21,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -40,6 +41,7 @@ import static org.junit.jupiter.api.Assertions.fail;
*/
public class TestLinkedBlockingDeque {
+ private static final Duration TIMEOUT_50_MILLIS = Duration.ofMillis(50);
private static final Integer ONE = Integer.valueOf(1);
private static final Integer TWO = Integer.valueOf(2);
private static final Integer THREE = Integer.valueOf(3);
@@ -148,9 +150,9 @@ public class TestLinkedBlockingDeque {
deque.offerFirst(null);
fail("Not supposed to get here");
} catch (final NullPointerException e) {}
- assertTrue(deque.offerFirst(ONE, 50, TimeUnit.MILLISECONDS));
- assertTrue(deque.offerFirst(TWO, 50, TimeUnit.MILLISECONDS));
- assertFalse(deque.offerFirst(THREE, 50, TimeUnit.MILLISECONDS));
+ assertTrue(deque.offerFirst(ONE, TIMEOUT_50_MILLIS));
+ assertTrue(deque.offerFirst(TWO, TIMEOUT_50_MILLIS));
+ assertFalse(deque.offerFirst(THREE, TIMEOUT_50_MILLIS));
}
@Test
@@ -159,9 +161,9 @@ public class TestLinkedBlockingDeque {
deque.offerLast(null);
fail("Not supposed to get here");
} catch (final NullPointerException e) {}
- assertTrue(deque.offerLast(ONE, 50, TimeUnit.MILLISECONDS));
- assertTrue(deque.offerLast(TWO, 50, TimeUnit.MILLISECONDS));
- assertFalse(deque.offerLast(THREE, 50, TimeUnit.MILLISECONDS));
+ assertTrue(deque.offerLast(ONE, TIMEOUT_50_MILLIS));
+ assertTrue(deque.offerLast(TWO, TIMEOUT_50_MILLIS));
+ assertFalse(deque.offerLast(THREE, TIMEOUT_50_MILLIS));
}
@Test
@@ -229,13 +231,13 @@ public class TestLinkedBlockingDeque {
@Test
public void testPollFirstWithTimeout() throws InterruptedException {
assertNull(deque.pollFirst());
- assertNull(deque.pollFirst(50, TimeUnit.MILLISECONDS));
+ assertNull(deque.pollFirst(TIMEOUT_50_MILLIS));
}
@Test
public void testPollLastWithTimeout() throws InterruptedException {
assertNull(deque.pollLast());
- assertNull(deque.pollLast(50, TimeUnit.MILLISECONDS));
+ assertNull(deque.pollLast(TIMEOUT_50_MILLIS));
}
@Test
@@ -323,11 +325,11 @@ public class TestLinkedBlockingDeque {
@Test
public void testOfferWithTimeout() throws InterruptedException {
- assertTrue(deque.offer(ONE, 50, TimeUnit.MILLISECONDS));
- assertTrue(deque.offer(TWO, 50, TimeUnit.MILLISECONDS));
- assertFalse(deque.offer(THREE, 50, TimeUnit.MILLISECONDS));
+ assertTrue(deque.offer(ONE, TIMEOUT_50_MILLIS));
+ assertTrue(deque.offer(TWO, TIMEOUT_50_MILLIS));
+ assertFalse(deque.offer(THREE, TIMEOUT_50_MILLIS));
try {
- deque.offer(null, 50, TimeUnit.MILLISECONDS);
+ deque.offer(null, TIMEOUT_50_MILLIS);
fail("Not supposed to get here");
} catch (final NullPointerException e) {}
}
@@ -352,8 +354,8 @@ public class TestLinkedBlockingDeque {
@Test
public void testPollWithTimeout() throws InterruptedException {
- assertNull(deque.poll(50, TimeUnit.MILLISECONDS));
- assertNull(deque.poll(50, TimeUnit.MILLISECONDS));
+ assertNull(deque.poll(TIMEOUT_50_MILLIS));
+ assertNull(deque.poll(TIMEOUT_50_MILLIS));
}
@Test