CodeWalk

Java 21 ScopedValue与SequencedCollection新特性

作者:孤独的心 · 2026-05-30 12:55

请详细解释Java 21引入的两个新特性:ScopedValue(作用域值,比ThreadLocal更高效的线程本地值传递方案)和SequencedCollection(序列化集合接口,为集合添加顺序相关的操作)。它们分别解决了什么问题?如何使用?

回答

孤独的心

ScopedValue(JEP 429,孵化器)

问题:ThreadLocal的缺点——①每个线程独立存储,虚拟线程场景下内存巨大;②无继承机制;③可修改,易导致数据泄漏。

ScopedValue:不可变线程本地值,绑定到某个作用域生命周期。

// 定义
private static final ScopedValue<String> USER = ScopedValue.newInstance();

// 绑定值到作用域
ScopedValue.where(USER, "admin").run(() -> {
    // 在这个Runnable中,USER的值是"admin"
    String user = USER.get(); // "admin"
    // 调用其他方法也能获取,自动传递
    process();
});
// 离开作用域后,USER无值

// 不可变性
ScopedValue.where(USER, "user1").run(() -> {
    ScopedValue.where(USER, "user2").run(() -> {
        // USER.get() == "user2",外层值被隐藏
    });
    // USER.get() == "user1",恢复
});

优势:无需线程本地存储、支持嵌套作用域、不可变更安全。

SequencedCollection(JEP 431)

问题:Java集合缺乏统一的顺序操作接口。

新增接口层次

// 顺序集合接口
interface SequencedCollection<E> extends Collection<E> {
    SequencedCollection<E> reversed();  // 逆序视图
    E getFirst(); / E getLast();
    void addFirst(E); / void addLast(E);
    E removeFirst(); / E removeLast();
}

// 顺序Set
interface SequencedSet<E> extends Set<E>, SequencedCollection<E>

// 顺序Map
interface SequencedMap<K,V> extends Map<K,V> {
    SequencedMap<K,V> reversed();
    Entry<K,V> firstEntry(); / Entry<K,V> lastEntry();
    K firstKey(); / K lastKey();
}

实现类更新:LinkedHashMap、LinkedHashSet、TreeMap、TreeSet、ArrayList、ArrayDeque等实现了新接口。

var list = new ArrayList<>(List.of(1, 2, 3));
list.addFirst(0);    // [0, 1, 2, 3]
list.addLast(4);     // [0, 1, 2, 3, 4]
list.reversed();     // [4, 3, 2, 1, 0]