What is TREEIFY_THRESHOLD and UNTREEIFY_THRESHOLD? — Cracked Java
// Java Collections Framework · Map, HashMap Internals
SeniorTheory

What is TREEIFY_THRESHOLD and UNTREEIFY_THRESHOLD?

TREEIFY_THRESHOLD = 8 is the chain length that promotes a bucket to a red-black tree. UNTREEIFY_THRESHOLD = 6 is the size that demotes it back to a linked list during resize. The gap of 2 prevents thrashing.

The constants

static final int TREEIFY_THRESHOLD    = 8;
static final int UNTREEIFY_THRESHOLD  = 6;
static final int MIN_TREEIFY_CAPACITY = 64;

Why a gap?

If both thresholds were the same — say 8 — a bucket sitting right at the boundary would flip between list and tree on every insert/remove. Each conversion involves walking the bucket, allocating TreeNode wrappers (or unwrapping them), and re-linking pointers. That's pure overhead.

By making demotion happen at 6 instead of 8, the bucket has to meaningfully shrink — by at least 2 entries — before paying the cost of going back to a list. This is classic hysteresis: the same idea used in thermostats, voltage regulators, and any feedback loop where you don't want oscillation at the threshold.

chain length:   ... 5  6  7  8  9 ...
                     ^     ^
                     |     |
            UNTREEIFY     TREEIFY
            (6)           (8)
            
once a tree, stays a tree until size drops to 6
once a list, stays a list until size grows to 8
Hysteresis prevents flipping at the boundary

When does untreeify actually run?

Only during resize(). When the table doubles, each bucket is split via the (hash & oldCap) bit. If a tree bucket splits into pieces of size ≤ 6, those pieces become linked lists again. Untreeify does not happen on plain remove — a tree that drops to 5 entries after a deletion stays a tree until the next resize touches it.

// pseudo-flow inside resize() for a treeified bucket
if (loTreeSize <= UNTREEIFY_THRESHOLD) {
    convertLoToList();
} else {
    treeifyLo();
}
// same for the hi half

Why exactly 8 and 6?

8 falls into the Poisson tail where natural collisions vanish (probability < 10⁻⁷ per bucket at load factor 0.75), so reaching 8 strongly implies bad keys — exactly when you want a tree's worst-case bound. 6 is a comfortable margin below that: small enough that a list is clearly cheaper than tree overhead, large enough that small fluctuations don't trigger a flip.

Mark your status