Ответ 1
В то время как вы должны, конечно, стараться как можно эффективнее, нет произвольного ограничения количества потоков, которые вы разрешаете, все зависит от того, как вы структурируете свой код.
Класс ThreadPoolExecutor
очень хорошо документирован, и именно там возникает проблема, с которой вы сталкиваетесь. Я бы рекомендую прочитать его, проверьте
Для начала я предполагаю, что вы строите это с помощью Ant и не используете эти параметры на своем javac node:
<javac debug="true" debuglevel="lines,vars,source" />
Либо это, либо обфускатор, который вы, по-видимому, используете, является причиной того, что то, что обычно является самой важной частью трассировки стека, вместо этого просто выводит:
c.onProgressUpdate(Unknown Source)
Это текущий источник ICS 4.0.4 для ThreadPoolExecutor.AbortPolicy, поскольку вы можете видеть, что это в основном ловушка, которая всегда выдает исключение:
/**
* A handler for rejected tasks that throws a
* {@code RejectedExecutionException}.
*/
public static class AbortPolicy implements RejectedExecutionHandler {
/**
* Creates an {@code AbortPolicy}.
*/
public AbortPolicy() { }
/**
* Always throws RejectedExecutionException.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
* @throws RejectedExecutionException always.
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
Кроме того, вы найдете объявленный по умолчаниюHandler в верхней части ThreadPoolExecutor:
private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();
Итак, если вы посмотрите на конструктор по умолчанию для ThreadPoolExecutor:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
Вы увидите, что он сам создает экземпляр, используя класс AbortPolicy
, который по умолчанию имеет значение RejectedExecutionHandler
.
ThreadPoolExecutor
также включает несколько других подклассов RejectedExecutionHandler
, которые вы могли бы установить по умолчанию, например:
/**
* A handler for rejected tasks that silently discards the
* rejected task.
*/
public static class DiscardPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code DiscardPolicy}.
*/
public DiscardPolicy() { }
/**
* Does nothing, which has the effect of discarding task r.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
}
Другие 3 ThreadPoolExecutor
конструкторы включают в себя параметр обработчика, поэтому вы можете либо создать его экземпляр с помощью другого обработчика, либо создать собственный подкласс, аналогичный этому:
package com.justinbuser;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class NoThrowThreadPool extends ThreadPoolExecutor {
private static final RejectedExecutionHandler defaultHandler = new AdoptPolicy();
public NoThrowThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler);
setRejectedExecutionHandler(defaultHandler);
}
public NoThrowThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler);
}
public NoThrowThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler);
}
public NoThrowThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory, RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler);
}
public static class AdoptPolicy extends ThreadPoolExecutor.AbortPolicy {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()).printStackTrace();
}
}
}