crossoverJie/JCSprout · error · NullPointerException
runnable nullPointerException
Error message
runnable nullPointerException
What it means
CustomThreadPool.execute() throws a NullPointerException when the submitted Runnable is null, mirroring the contract of java.util.concurrent.ThreadPoolExecutor.execute(). The pool needs a concrete task to schedule onto a worker thread, so a null reference is treated as a programmer error rather than silently ignored.
Source
Thrown at src/main/java/com/crossoverjie/concurrent/CustomThreadPool.java:117
* @param callable
* @param <T>
* @return
*/
public <T> Future<T> submit(Callable<T> callable) {
FutureTask<T> future = new FutureTask(callable);
execute(future);
return future;
}
/**
* 执行任务
*
* @param runnable 需要执行的任务
*/
public void execute(Runnable runnable) {
if (runnable == null) {
throw new NullPointerException("runnable nullPointerException");
}
if (isShutDown.get()) {
LOGGER.info("线程池已经关闭,不能再提交任务!");
return;
}
//提交的线程 计数
totalTask.incrementAndGet();
//小于最小线程数时新建线程
if (workers.size() < miniSize) {
addWorker(runnable);
return;
}
boolean offer = workQueue.offer(runnable);
//写入队列失败View on GitHub (pinned to fc4c6e5f6d)
Solutions
- Ensure the Runnable passed to execute()/submit() is never null — assign a no-op or throw a clearer IllegalArgumentException in your own code first.
- If the task is optional, guard the call: if (runnable != null) pool.execute(runnable);
- When calling submit(), validate the Callable argument before passing it.
Example fix
// before
pool.execute(maybeNullTask);
// after
if (runnable != null) {
pool.execute(runnable);
} else {
LOGGER.warn("skipping null task submission");
} Defensive patterns
Strategy: validation
Validate before calling
Objects.requireNonNull(runnable, "runnable must not be null before submitting to pool"); pool.execute(runnable);
Prevention
- Always validate task arguments with Objects.requireNonNull before calling execute() or submit().
- Avoid conditional expressions that can yield null (condition ? task : null); use an explicit if-guard instead.
- If tasks come from a factory, have the factory return an empty Runnable rather than null.
When it happens
Trigger: Calling execute(null) directly, or submit(callable) where callable is null (submit wraps the callable in a FutureTask and forwards to execute). Also triggered when a method reference or supplier returns null and the result is passed in.
Common situations: Passing a conditional expression that evaluates to null (e.g. condition ? task : null). Submitting a task obtained from a factory or lookup that can return null. Copy-paste where the runnable variable was never assigned.
Related errors
AI-assisted analysis of crossoverJie/JCSprout@fc4c6e5f6d (2026-08-14).
Data as JSON: /api/errors/c43716846b4667bc.
Report an issue: GitHub.