- Remove busy wait from AtomicSafeInitializer.get()DiffBuilder.append(String, Object left, Object right) does not do a left.equals(right) checkStrSubstitutor.replaceSystemProperties does not work consistentlyAdd option to disable the "objectsTriviallyEqual" test in DiffBuilder
diff --git a/src/main/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializer.java b/src/main/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializer.java
index a1186dba2..5bb5096db 100644
--- a/src/main/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializer.java
+++ b/src/main/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializer.java
@@ -16,7 +16,6 @@
*/
package org.apache.commons.lang3.concurrent;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -63,44 +62,20 @@ public abstract class AtomicSafeInitializer implements
/** Holds the reference to the managed object. */
private final AtomicReference reference = new AtomicReference();
- /** Holds the exception that terminated the initialize() method, if an exception was thrown */
- private final AtomicReference referenceExc = new AtomicReference();
-
- /** Latch for those threads waiting for initialization to complete. */
- private final CountDownLatch latch = new CountDownLatch(1);
-
/**
* Get (and initialize, if not initialized yet) the required object
*
* @return lazily initialized object
* @throws ConcurrentException if the initialization of the object causes an
- * exception or the thread is interrupted waiting for another thread to
- * complete the initialization
+ * exception
*/
@Override
public final T get() throws ConcurrentException {
T result;
- if ((result = reference.get()) == null) {
+ while ((result = reference.get()) == null) {
if (factory.compareAndSet(null, this)) {
- try {
- reference.set(result = initialize());
- } catch ( ConcurrentException exc ) {
- referenceExc.set(exc);
- throw exc;
- } finally {
- latch.countDown();
- }
- } else {
- try {
- latch.await();
- if ( referenceExc.get() != null ) {
- throw new ConcurrentException(referenceExc.get().getMessage(), referenceExc.get().getCause());
- }
- result = reference.get();
- } catch (InterruptedException intExc) {
- throw new ConcurrentException("interrupted waiting for initialization to complete", intExc);
- }
+ reference.set(initialize());
}
}
diff --git a/src/test/java/org/apache/commons/lang3/concurrent/AbstractConcurrentInitializerTest.java b/src/test/java/org/apache/commons/lang3/concurrent/AbstractConcurrentInitializerTest.java
index d3fd4c129..6bd8204af 100644
--- a/src/test/java/org/apache/commons/lang3/concurrent/AbstractConcurrentInitializerTest.java
+++ b/src/test/java/org/apache/commons/lang3/concurrent/AbstractConcurrentInitializerTest.java
@@ -18,8 +18,6 @@ package org.apache.commons.lang3.concurrent;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
import java.util.concurrent.CountDownLatch;
@@ -74,41 +72,7 @@ public abstract class AbstractConcurrentInitializerTest {
@Test
public void testGetConcurrent() throws ConcurrentException,
InterruptedException {
-
- this.testGetConcurrentOptionallyWithException(false, null, null);
- }
-
- /**
- * Tests the handling of exceptions thrown on the initialized when multiple threads execute concurrently.
- * Always an exception with the same message and cause should be thrown.
- *
- * @throws org.apache.commons.lang3.concurrent.ConcurrentException because the object under test may throw it
- * @throws java.lang.InterruptedException because the threading API my throw it
- */
- public void testGetConcurrentWithException(String expectedMessage,
- Exception expectedCause)
- throws ConcurrentException, InterruptedException {
-
- this.testGetConcurrentOptionallyWithException(true, expectedMessage, expectedCause);
- }
-
- /**
- * Tests whether get() can be invoked from multiple threads concurrently. Supports the exception-handling case
- * and the normal, non-exception case.
- *
- * Always the same object should be returned, or an exception with the same message and cause should be thrown.
- *
- * @throws org.apache.commons.lang3.concurrent.ConcurrentException because the object under test may throw it
- * @throws java.lang.InterruptedException because the threading API my throw it
- */
- protected void testGetConcurrentOptionallyWithException(boolean expectExceptions, String expectedMessage,
- Exception expectedCause)
- throws ConcurrentException, InterruptedException {
-
- final ConcurrentInitializer