You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by br...@apache.org on 2015/02/26 09:13:59 UTC
svn commit: r1662379 - in /commons/proper/lang/trunk/src: changes/
main/java/org/apache/commons/lang3/concurrent/
test/java/org/apache/commons/lang3/concurrent/
Author: britter
Date: Thu Feb 26 08:13:58 2015
New Revision: 1662379
URL: http://svn.apache.org/r1662379
Log:
Reverting changes from r1661762 (LANG-1086) for now until we have consensus about this change.
Modified:
commons/proper/lang/trunk/src/changes/changes.xml
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializer.java
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AbstractConcurrentInitializerTest.java
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AtomicInitializerTest.java
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializerTest.java
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/LazyInitializerTest.java
Modified: commons/proper/lang/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/changes/changes.xml?rev=1662379&r1=1662378&r2=1662379&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/changes/changes.xml [utf-8] (original)
+++ commons/proper/lang/trunk/src/changes/changes.xml [utf-8] Thu Feb 26 08:13:58 2015
@@ -22,7 +22,6 @@
<body>
<release version="3.4" date="tba" description="tba">
- <action issue="LANG-1086" type="update" dev="britter">Remove busy wait from AtomicSafeInitializer.get()</action>
<action issue="LANG-1081" type="fix" dev="britter" due-to="Jonathan Baker">DiffBuilder.append(String, Object left, Object right) does not do a left.equals(right) check</action>
<action issue="LANG-1055" type="fix" dev="britter" due-to="Jonathan Baker">StrSubstitutor.replaceSystemProperties does not work consistently</action>
<action issue="LANG-1082" type="add" dev="britter" due-to="Jonathan Baker">Add option to disable the "objectsTriviallyEqual" test in DiffBuilder</action>
Modified: commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializer.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializer.java?rev=1662379&r1=1662378&r2=1662379&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializer.java (original)
+++ commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializer.java Thu Feb 26 08:13:58 2015
@@ -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 AtomicSafeInitiali
/** Holds the reference to the managed object. */
private final AtomicReference<T> reference = new AtomicReference<T>();
- /** Holds the exception that terminated the initialize() method, if an exception was thrown */
- private final AtomicReference<ConcurrentException> referenceExc = new AtomicReference<ConcurrentException>();
-
- /** 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());
}
}
Modified: commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AbstractConcurrentInitializerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AbstractConcurrentInitializerTest.java?rev=1662379&r1=1662378&r2=1662379&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AbstractConcurrentInitializerTest.java (original)
+++ commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AbstractConcurrentInitializerTest.java Thu Feb 26 08:13:58 2015
@@ -18,8 +18,6 @@ package org.apache.commons.lang3.concurr
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 AbstractConcurrent
@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<Object> initializer = expectExceptions ?
- createExceptionThrowingInitializer() :
- createInitializer();
-
+ final ConcurrentInitializer<Object> initializer = createInitializer();
final int threadCount = 20;
final CountDownLatch startLatch = new CountDownLatch(1);
class GetThread extends Thread {
@@ -142,18 +106,9 @@ public abstract class AbstractConcurrent
}
// check results
- if ( expectExceptions ) {
- for (GetThread t : threads) {
- assertTrue(t.object instanceof Exception);
- Exception exc = (Exception) t.object;
- assertEquals(expectedMessage, exc.getMessage());
- assertSame(expectedCause, exc.getCause());
- }
- } else {
- final Object managedObject = initializer.get();
- for (final GetThread t : threads) {
- assertEquals("Wrong object", managedObject, t.object);
- }
+ final Object managedObject = initializer.get();
+ for (final GetThread t : threads) {
+ assertEquals("Wrong object", managedObject, t.object);
}
}
@@ -164,12 +119,4 @@ public abstract class AbstractConcurrent
* @return the initializer object to be tested
*/
protected abstract ConcurrentInitializer<Object> createInitializer();
-
- /**
- * Creates a {@link ConcurrentInitializer} object that always throws
- * exceptions.
- *
- * @return
- */
- protected abstract ConcurrentInitializer<Object> createExceptionThrowingInitializer();
}
Modified: commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AtomicInitializerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AtomicInitializerTest.java?rev=1662379&r1=1662378&r2=1662379&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AtomicInitializerTest.java (original)
+++ commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AtomicInitializerTest.java Thu Feb 26 08:13:58 2015
@@ -16,29 +16,12 @@
*/
package org.apache.commons.lang3.concurrent;
-import org.junit.Test;
-
/**
* Test class for {@code AtomicInitializer}.
*
* @version $Id$
*/
public class AtomicInitializerTest extends AbstractConcurrentInitializerTest {
- private Exception testCauseException;
- private String testExceptionMessage;
-
- public AtomicInitializerTest() {
- testExceptionMessage = "x-test-exception-message-x";
- testCauseException = new Exception(testExceptionMessage);
- }
-
- @Test
- public void testGetConcurrentWithException ()
- throws ConcurrentException, InterruptedException {
-
- super.testGetConcurrentWithException(testExceptionMessage, testCauseException);
- }
-
/**
* Returns the initializer to be tested.
*
@@ -53,20 +36,4 @@ public class AtomicInitializerTest exten
}
};
}
-
- @Override
- protected ConcurrentInitializer<Object> createExceptionThrowingInitializer() {
- return new ExceptionThrowingAtomicSafeInitializerTestImpl();
- }
-
- /**
- * A concrete test implementation of {@code AtomicSafeInitializer}. This
- * implementation always throws an exception.
- */
- private class ExceptionThrowingAtomicSafeInitializerTestImpl extends AtomicSafeInitializer<Object> {
- @Override
- protected Object initialize() throws ConcurrentException {
- throw new ConcurrentException(testExceptionMessage, testCauseException);
- }
- }
}
Modified: commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializerTest.java?rev=1662379&r1=1662378&r2=1662379&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializerTest.java (original)
+++ commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/AtomicSafeInitializerTest.java Thu Feb 26 08:13:58 2015
@@ -17,11 +17,7 @@
package org.apache.commons.lang3.concurrent;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Before;
@@ -34,19 +30,12 @@ import org.junit.Test;
*/
public class AtomicSafeInitializerTest extends
AbstractConcurrentInitializerTest {
-
/** The instance to be tested. */
private AtomicSafeInitializerTestImpl initializer;
- private ExceptionThrowingAtomicSafeInitializerTestImpl exceptionThrowingInitializer;
- private Exception testCauseException;
- private String testExceptionMessage;
@Before
public void setUp() throws Exception {
initializer = new AtomicSafeInitializerTestImpl();
- exceptionThrowingInitializer = new ExceptionThrowingAtomicSafeInitializerTestImpl();
- testExceptionMessage = "x-test-exception-message-x";
- testCauseException = new Exception(testExceptionMessage);
}
/**
@@ -60,17 +49,6 @@ public class AtomicSafeInitializerTest e
}
/**
- * Returns the exception-throwing initializer to be tested.
- *
- * @return the {@code AtomicSafeInitializer} under test when validating
- * exception handling
- */
- @Override
- protected ConcurrentInitializer<Object> createExceptionThrowingInitializer() {
- return exceptionThrowingInitializer;
- }
-
- /**
* Tests that initialize() is called only once.
*
* @throws org.apache.commons.lang3.concurrent.ConcurrentException because {@link #testGetConcurrent()} may throw it
@@ -84,92 +62,6 @@ public class AtomicSafeInitializerTest e
initializer.initCounter.get());
}
- @Test
- public void testExceptionOnInitialize() throws ConcurrentException,
- InterruptedException {
-
- testGetConcurrentWithException(testExceptionMessage, testCauseException);
- }
-
- /**
- * Validate the handling of an interrupted exception on a thread waiting for another thread to finish calling the
- * initialize() method.
- *
- * @throws Exception
- */
- @Test(timeout = 3000)
- public void testInterruptedWaitingOnInitialize() throws Exception {
- this.execTestWithWaitingOnInitialize(true);
- }
-
- /**
- * Test the success path of two threads reaching the initialization point at the same time.
- */
- @Test(timeout = 3000)
- public void testOneThreadWaitingForAnotherToInitialize () throws Exception {
- execTestWithWaitingOnInitialize(false);
- }
-
-
- /**
- * Execute a test that requires one thread to be waiting on the initialize() method of another thread. This test
- * uses latches to guarantee the code path being tested.
- *
- * @throws Exception
- */
- protected void execTestWithWaitingOnInitialize(boolean interruptInd) throws Exception {
- final CountDownLatch startLatch = new CountDownLatch(1);
- final CountDownLatch finishLatch = new CountDownLatch(1);
- final WaitingInitializerTestImpl initializer = new WaitingInitializerTestImpl(startLatch, finishLatch);
-
- InitializerTestThread execThread1 = new InitializerTestThread(initializer);
- InitializerTestThread execThread2 = new InitializerTestThread(initializer);
-
- // Start the first thread and wait for it to get into the initialize method so we are sure it is the thread
- // executing initialize().
- execThread1.start();
- startLatch.await();
-
- // Start the second thread and interrupt it to force the InterruptedException. There is no need to make sure
- // the thread reaches the await() call before interrupting it.
- execThread2.start();
-
- if ( interruptInd ) {
- // Interrupt the second thread now and wait for it to complete to ensure it reaches the wait inside the
- // get() method.
- execThread2.interrupt();
- execThread2.join();
- }
-
- // Signal the completion of the initialize method now.
- finishLatch.countDown();
-
- // Wait for the initialize() to finish.
- execThread1.join();
-
- // Wait for thread2 to finish, if it was not already done
- if ( ! interruptInd ) {
- execThread2.join();
- }
-
- //
- // Validate: thread1 should have the valid result; thread2 should have caught an interrupted exception, if
- // interrupted, or should have the same result otherwise.
- //
- assertFalse(execThread1.isCaughtException());
- assertSame(initializer.getAnswer(), execThread1.getResult());
-
- if ( interruptInd ) {
- assertTrue(execThread2.isCaughtException());
- Exception exc = (Exception) execThread2.getResult();
- assertTrue(exc.getCause() instanceof InterruptedException);
- assertEquals("interrupted waiting for initialization to complete", exc.getMessage());
- } else {
- assertFalse(execThread2.isCaughtException());
- assertSame(initializer.getAnswer(), execThread2.getResult());
- }
- }
-
/**
* A concrete test implementation of {@code AtomicSafeInitializer}. This
* implementation also counts the number of invocations of the initialize()
@@ -186,90 +78,4 @@ public class AtomicSafeInitializerTest e
return new Object();
}
}
-
- /**
- * A concrete test implementation of {@code AtomicSafeInitializer}. This
- * implementation always throws an exception.
- */
- private class ExceptionThrowingAtomicSafeInitializerTestImpl extends AtomicSafeInitializer<Object> {
- @Override
- protected Object initialize() throws ConcurrentException {
- throw new ConcurrentException(testExceptionMessage, testCauseException);
- }
- }
-
- /**
- * Initializer that signals it has started and waits to complete until signalled in order to enable a guaranteed
- * order-of-operations. This allows the test code to peg one thread to the initialize method for a period of time
- * that the test can dictate.
- */
- private class WaitingInitializerTestImpl extends AtomicSafeInitializer<Object> {
- private final CountDownLatch startedLatch;
- private final CountDownLatch finishLatch;
- private final Object answer = new Object();
-
- public WaitingInitializerTestImpl(CountDownLatch startedLatch, CountDownLatch finishLatch) {
- this.startedLatch = startedLatch;
- this.finishLatch = finishLatch;
- }
-
- @Override
- protected Object initialize() throws ConcurrentException {
- this.startedLatch.countDown();
- try {
- this.finishLatch.await();
- } catch (InterruptedException intExc) {
- throw new ConcurrentException(intExc);
- }
-
- return answer;
- }
-
- public Object getAnswer () {
- return answer;
- }
- }
-
- /**
- * Test executor of the initializer get() operation that captures the result.
- */
- private class InitializerTestThread extends Thread {
- private AtomicSafeInitializer<Object> initializer;
- private Object result;
- private boolean caughtException;
-
- public InitializerTestThread(AtomicSafeInitializer<Object> initializer) {
- super("AtomicSafeInitializer test thread");
- this.initializer = initializer;
- }
-
- @Override
- public void run() {
- try {
- this.result = initializer.get();
- } catch ( ConcurrentException concurrentExc ) {
- this.caughtException = true;
- this.result = concurrentExc;
- }
- }
-
- /**
- * Resulting object, if the get() method returned successfully, or exception if an exception was thrown.
- *
- * @return resulting object or exception from the get() method call.
- */
- public Object getResult () {
- return this.result;
- }
-
- /**
- * Determine whether an exception was caught on the get() call. Does not guarantee that the get() method was
- * called or completed.
- *
- * @return true => exception was caught; false => exception was not caught.
- */
- public boolean isCaughtException () {
- return this.caughtException;
- }
- }
}
Modified: commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/LazyInitializerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/LazyInitializerTest.java?rev=1662379&r1=1662378&r2=1662379&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/LazyInitializerTest.java (original)
+++ commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/concurrent/LazyInitializerTest.java Thu Feb 26 08:13:58 2015
@@ -17,7 +17,6 @@
package org.apache.commons.lang3.concurrent;
import org.junit.Before;
-import org.junit.Test;
/**
* Test class for {@code LazyInitializer}.
@@ -27,16 +26,10 @@ import org.junit.Test;
public class LazyInitializerTest extends AbstractConcurrentInitializerTest {
/** The initializer to be tested. */
private LazyInitializerTestImpl initializer;
- private ExceptionThrowingLazyInitializerTestImpl exceptionThrowingInitializer;
- private Exception testCauseException;
- private String testExceptionMessage;
@Before
public void setUp() throws Exception {
initializer = new LazyInitializerTestImpl();
- exceptionThrowingInitializer = new ExceptionThrowingLazyInitializerTestImpl();
- testExceptionMessage = "x-test-exception-message-x";
- testCauseException = new Exception(testExceptionMessage);
}
/**
@@ -50,18 +43,6 @@ public class LazyInitializerTest extends
return initializer;
}
- @Override
- protected ConcurrentInitializer<Object> createExceptionThrowingInitializer() {
- return exceptionThrowingInitializer;
- }
-
- @Test
- public void testGetConcurrentWithException ()
- throws ConcurrentException, InterruptedException {
-
- super.testGetConcurrentWithException(testExceptionMessage, testCauseException);
- }
-
/**
* A test implementation of LazyInitializer. This class creates a plain
* Object. As Object does not provide a specific equals() method, it is easy
@@ -74,16 +55,4 @@ public class LazyInitializerTest extends
return new Object();
}
}
-
-
- /**
- * A concrete test implementation of {@code AtomicSafeInitializer}. This
- * implementation always throws an exception.
- */
- private class ExceptionThrowingLazyInitializerTestImpl extends LazyInitializer<Object> {
- @Override
- protected Object initialize() throws ConcurrentException {
- throw new ConcurrentException(testExceptionMessage, testCauseException);
- }
- }
}