crossoverJie/JCSprout · error · IllegalArgumentException

counter < 0

Error message

counter < 0

What it means

The constructor of MultipleThreadCountDownKit (a custom CountDownLatch) rejects a negative initial count with IllegalArgumentException. A countdown latch needs a non-negative starting counter; a negative value has no meaningful semantics for tracking how many threads must report completion.

Source

Thrown at src/main/java/com/crossoverjie/concurrent/communication/MultipleThreadCountDownKit.java:28

 * @since JDK 1.8
 */
public final class MultipleThreadCountDownKit {

    /**
     * 计数器
     */
    private AtomicInteger counter;

    /**
     * 通知对象
     */
    private Object notify ;

    private Notify notifyListen ;

    public MultipleThreadCountDownKit(int number){
        if (number < 0) {
            throw new IllegalArgumentException("counter < 0");
        }
        counter = new AtomicInteger(number) ;
        notify = new Object() ;
    }

    /**
     * 设置回调接口
     * @param notify
     */
    public void setNotify(Notify notify){
        notifyListen = notify ;
    }


    /**
     * 线程完成后计数 -1
     */
    public void countDown(){

View on GitHub (pinned to fc4c6e5f6d)

Solutions

  1. Validate the count before construction and reject or clamp it in your calling code.
  2. If the count can legitimately be zero, guard with Math.max(0, computedCount).
  3. Review the arithmetic that produces the count to ensure it cannot go negative under any input.

Example fix

// before
new MultipleThreadCountDownKit(totalTasks - reservedSlots); // negative if reserved > total

// after
int count = Math.max(0, totalTasks - reservedSlots);
new MultipleThreadCountDownKit(count);
Defensive patterns

Strategy: validation

Validate before calling

if (number < 0) {
    throw new IllegalArgumentException("count must be >= 0, got " + number);
}
MultipleThreadCountDownKit latch = new MultipleThreadCountDownKit(number);

Prevention

When it happens

Trigger: Constructing new MultipleThreadCountDownKit(-1) or any negative int. Note that 0 IS permitted — it means all work is already considered complete, so await() returns immediately and countDown() is a no-op.

Common situations: Computing the count from a subtraction or list-size that can go negative (e.g. new MultipleThreadCountDownKit(total - reserved) where reserved > total). Passing an unvalidated value parsed from configuration or a request parameter.

Related errors


AI-assisted analysis of crossoverJie/JCSprout@fc4c6e5f6d (2026-08-14). Data as JSON: /api/errors/6ae23ff302aee915. Report an issue: GitHub.