Хотя вы, конечно, должны стараться поддерживать максимальную эффективность, произвольного ограничения на количество потоков, которые вам «разрешено» запускать, нет, все зависит от того, как вы структурируете свой код.
Класс ThreadPoolExecutor
чрезвычайно хорошо документирован, и именно здесь возникает проблема, с которой вы сталкиваетесь.Я бы рекомендовал прочитать его , посмотрите
Для начала я предполагаю, что вы строите это с помощью Ant и не используете эти параметры на своем узле javac:
<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());
}
}
Кроме того, вы найдете defaultHandler, объявленный в верхней части 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) {
}
}
Другие 3ThreadPoolExecutor
конструкторы включают опцию обработчика, так что вы можете либо создать ее экземпляр, используя другой обработчик, либо создать свой собственный подкласс, подобный этому:
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();
}
}
}