(Mostly) update for Spring Integration changes
This commit is contained in:
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.batch.repeat.support;
|
||||
|
||||
import org.springframework.batch.repeat.RepeatException;
|
||||
|
||||
/**
|
||||
* Abstract implementation that can be extended for both Backport Concurrent and
|
||||
* JDK 5 Concurrent.
|
||||
*
|
||||
* @author Ben Hale
|
||||
* @author Dave Syer
|
||||
*/
|
||||
abstract class AbstractResultQueue extends RepeatInternalStateSupport implements ResultQueue {
|
||||
|
||||
// Arbitrary lock 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.
|
||||
private volatile int count = 0;
|
||||
|
||||
public boolean isExpecting() {
|
||||
synchronized (lock) {
|
||||
// Base the decision about whether we expect more results on a
|
||||
// counter of the number of expected results actually collected.
|
||||
return count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void expect() {
|
||||
try {
|
||||
synchronized (lock) {
|
||||
aquireWait();
|
||||
count++;
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RepeatException("InterruptedException waiting for to acquire lock on input.");
|
||||
}
|
||||
}
|
||||
|
||||
public void put(ResultHolder holder) {
|
||||
// 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() {
|
||||
ResultHolder value;
|
||||
try {
|
||||
synchronized (lock) {
|
||||
value = takeResult();
|
||||
// Decrement the counter only when the result is collected.
|
||||
count--;
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RepeatException("InterruptedException while waiting for result.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire permission for one more task on the queue.
|
||||
*
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
protected abstract void aquireWait() throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Release the permit that we were holding while a task was processed.
|
||||
*/
|
||||
protected abstract void releaseWait();
|
||||
|
||||
/**
|
||||
* Add a {@link ResultHolder} with a finished result to the queue for
|
||||
* collection. Should not block. May throw an exception to signal that the
|
||||
* queue is full, but that would be an unexpected condition.
|
||||
*
|
||||
* @param resultHolder a {@link ResultHolder}
|
||||
*/
|
||||
protected abstract void addResult(ResultHolder resultHolder);
|
||||
|
||||
/**
|
||||
* Obtain a result from the queue, blocking until one becomes available.
|
||||
*
|
||||
* @return a {@link ResultHolder} with the completed result
|
||||
* @throws InterruptedException if an interrupt is signalled
|
||||
*/
|
||||
protected abstract ResultHolder takeResult() throws InterruptedException;
|
||||
|
||||
}
|
||||
@@ -20,12 +20,14 @@ import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import org.springframework.batch.repeat.RepeatException;
|
||||
|
||||
/**
|
||||
* An implementation of the {@link ResultQueue} that uses the Java 5 Concurrent Utilities.
|
||||
*
|
||||
* @author Ben Hale
|
||||
*/
|
||||
class JdkConcurrentResultQueue extends AbstractResultQueue implements RepeatInternalState {
|
||||
class JdkConcurrentResultQueue extends RepeatInternalStateSupport implements ResultQueue {
|
||||
|
||||
// Accumulation of result objects as they finish.
|
||||
private final BlockingQueue<ResultHolder> results;
|
||||
@@ -33,6 +35,10 @@ class JdkConcurrentResultQueue extends AbstractResultQueue implements RepeatInte
|
||||
// Accumulation of dummy objects flagging expected results in the future.
|
||||
private final Semaphore waits;
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
private volatile int count = 0;
|
||||
|
||||
JdkConcurrentResultQueue(int throttleLimit) {
|
||||
results = new LinkedBlockingQueue<ResultHolder>();
|
||||
waits = new Semaphore(throttleLimit);
|
||||
@@ -58,4 +64,49 @@ class JdkConcurrentResultQueue extends AbstractResultQueue implements RepeatInte
|
||||
return results.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isExpecting() {
|
||||
synchronized (lock) {
|
||||
// Base the decision about whether we expect more results on a
|
||||
// counter of the number of expected results actually collected.
|
||||
return count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void expect() {
|
||||
try {
|
||||
synchronized (lock) {
|
||||
aquireWait();
|
||||
count++;
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RepeatException("InterruptedException waiting for to acquire lock on input.");
|
||||
}
|
||||
}
|
||||
|
||||
public void put(ResultHolder holder) {
|
||||
// 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() {
|
||||
ResultHolder value;
|
||||
try {
|
||||
synchronized (lock) {
|
||||
value = takeResult();
|
||||
// Decrement the counter only when the result is collected.
|
||||
count--;
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RepeatException("InterruptedException while waiting for result.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ package org.springframework.batch.repeat.support;
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Ben Hale
|
||||
*
|
||||
* TODO: BlockingQueue with a CompletionService?
|
||||
*/
|
||||
interface ResultQueue extends RepeatInternalState {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user