I'm using ThreadPoolExecutor with LinkedBlockingQueue(Integer.MAX_VALUE) for multiple tasks, but why it throws RejectedExecutionException when submit(Callable task) within 2000 tasks in websphere? Shouldn't the queue be able to contain 2.1 billion tasks theoretically? Any information will be appreciated.
Two soap requests sent to my application will do two different jobs, each of these two jobs processing by a job class, and the will instance an custom ServiceExecutionFactory(bean with prototype) which acts as consumer and producer factory. The factory has an workQueue(size 1000) field to contain tasks the job class produced, and the consumer will take out the task in workQueue and put the task into thread pool. BTW,I can't reproduce this with Tomcat.
instance ThreadPoolExecutor
BlockingQueue<Runnable> executorQueue = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor tpe = (new ThreadPoolExecutor(poolSize, poolSize, 10, TimeUnit.SECONDS, executorQueue, tf));
tpe.allowCoreThreadTimeOut(true);
the executorService.submit(serviceInfo.getCallable()) may throw RejectedExecutionException because the threads are all occupied(including extern threads) and the Queue is full(I don’t know why this happens as I mentioned above). Then the program will catch the Exception and attempts to add it back to the queue, at this moment the workQueue(size 1000) of ServiceExecutionFactoryBase may be totally full and can’t add to it, it will throw queue full Exception using add() method. One more thing I feel also weird that the ConsumerService will rework after 3 hours later, but this ConsumerService thread should stop because of throw e statement, shouldn't it?
public class ConsumerService implements Callable<Object> {
public Object call() throws Exception {
// loop until interrupted
try {
while (true) {
// check the work queue for available item
ServiceInfo serviceInfo = queue.take();
// When an item is available, feed it to the executor, and save the future
try {
Future<Object> future = executorService.submit(serviceInfo.getCallable());
serviceInfo.setFuture(future);
serviceInfo.setCallable(null);
} catch (Exception e) {
if (serviceInfo.getRetrys() < getMaximumRequestRetries()) {
serviceInfo.setRetrys(serviceInfo.getRetrys() + 1);
queue.add(serviceInfo);
} else {
ServiceCaller sc = serviceInfo.getCallable();
sc.factory.notifyServiceAborted(sc.serviceKey, e);
}
}
}
} catch (InterruptedException e) {
// the job is done
return null;
} catch (Exception e) {
getLogger().error(e);
throw e;
}
}
}
I expect no RejectExecutionException occurs, but it does.