Java 21 ScopedValue与SequencedCollection新特性
请详细解释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]