diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/AbstractResultQueue.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/AbstractResultQueue.java index daf89b57c..9f34593a1 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/AbstractResultQueue.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/AbstractResultQueue.java @@ -28,14 +28,11 @@ import org.springframework.batch.repeat.RepeatException; abstract class AbstractResultQueue extends RepeatInternalStateSupport implements ResultQueue { // Arbitrary lock object. - Object lock = new Object(); - - // Arbitrary lock object. - Object hold = new Object(); + private final Object lock = new Object(); // Counter to monitor the difference between expected and actually collected // results. When this reaches zero there are really no more results. - volatile int count = 0; + private volatile int count = 0; public boolean isExpecting() { synchronized (lock) { @@ -59,15 +56,11 @@ abstract class AbstractResultQueue extends RepeatInternalStateSupport implements } public void put(ResultHolder holder) { - // There should be no need to block here, or to use offer(), but - // apparently the add() sometimes takes so long on the CI build that the - // queue fills up, so we synchronize here... - synchronized (hold) { - addResult(holder); - // Take from the waits queue now to allow another result to - // accumulate. But don't decrement the counter. - releaseWait(); - } + // There should be no need to block here, or to use offer() + addResult(holder); + // Take from the waits queue now to allow another result to + // accumulate. But don't decrement the counter. + releaseWait(); } public ResultHolder take() { diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/BackportConcurrentResultQueue.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/BackportConcurrentResultQueue.java index aef624998..f5b371836 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/BackportConcurrentResultQueue.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/BackportConcurrentResultQueue.java @@ -16,8 +16,8 @@ package org.springframework.batch.repeat.support; -import edu.emory.mathcs.backport.java.util.concurrent.ArrayBlockingQueue; import edu.emory.mathcs.backport.java.util.concurrent.BlockingQueue; +import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue; import edu.emory.mathcs.backport.java.util.concurrent.Semaphore; /** @@ -34,7 +34,7 @@ class BackportConcurrentResultQueue extends AbstractResultQueue implements Repea private final Semaphore waits; BackportConcurrentResultQueue(int throttleLimit) { - results = new ArrayBlockingQueue(throttleLimit); + results = new LinkedBlockingQueue(); waits = new Semaphore(throttleLimit); } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/JdkConcurrentResultQueue.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/JdkConcurrentResultQueue.java index 24012c8d8..b5b252306 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/JdkConcurrentResultQueue.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/JdkConcurrentResultQueue.java @@ -16,8 +16,8 @@ package org.springframework.batch.repeat.support; -import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.Semaphore; /** @@ -34,7 +34,7 @@ class JdkConcurrentResultQueue extends AbstractResultQueue implements RepeatInte private final Semaphore waits; JdkConcurrentResultQueue(int throttleLimit) { - results = new ArrayBlockingQueue(throttleLimit); + results = new LinkedBlockingQueue(); waits = new Semaphore(throttleLimit); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/AsynchronousRepeatTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/AsynchronousRepeatTests.java index 7d549f915..ec4a38cd1 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/AsynchronousRepeatTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/AsynchronousRepeatTests.java @@ -41,12 +41,16 @@ public class AsynchronousRepeatTests extends AbstractTradeBatchTests { final String threadName = Thread.currentThread().getName(); final Set threadNames = new HashSet(); - final RepeatCallback callback = new ItemReaderRepeatCallback(provider, processor) { + final RepeatCallback callback = new RepeatCallback() { public ExitStatus doInIteration(RepeatContext context) throws Exception { assertNotSame(threadName, Thread.currentThread().getName()); threadNames.add(Thread.currentThread().getName()); Thread.sleep(100); - return super.doInIteration(context); + Object item = provider.read(); + if (item!=null) { + processor.write(item); + } + return new ExitStatus(item!=null); } };