Skip to content

讨论一下StableValue #1

@liach

Description

@liach

看到作者在twi上介绍这个库的起因是看到Per Minborg说要研究StableValue(JDK自带的@Stable用API发布),暂时分享下看这个库的感想:(很多词不知道中文术语,将就看看吧)
现在公开能当stable用的功能基本都和class绑定,主要是<clinit>(Holder class)、indy(Lambda)、condy三种模式。这个仓库用indy模式再加一层class。
1、我个人设计API会设计个 MethodHandle initializer->MethodHandle memoized 模式,这样相当于动态Holder class,memoized指向Holder class static final field,Holder class 会呼叫initializer。
2、为了使用方便,API设计(比如这个项目)一般都实现一个接口。但是实现接口的问题是要创建实例,然后实例要调用stable功能就要专门用一个class,比如一个实现class自带indy/condy创建一次实例。这个为了支持接口相当于多一层class皮,但是这层皮里面能用condy indy还算不错。我个人倾向写condy,ConstantBootstraps.invoke + MethodHandle(Supplier.get) + MethodHandles.classData,定义时传入supplier当classdata,比这种用static field更安全。

这两个的最大问题都是每一个StableValue都要定义一个class,但是class定义多了吃内存,而且如果一个interface有太多实现,也会有profile pollution,尤其是放list里面。

相比之下,@Stable几乎没有任何成本,只需要字段额外占用一个全零值,同时赋值也更灵活。StableValue相比之下封装就很厚了。因为Java设计理念是下限比较高,然后stable玩坏的后果也比正常field玩坏的后果大,所以封装比较复杂,再写了一套dcl封装;但是还是比额外定义class成本更低,而且它基础的get+setIfUnset可以替代现有的atomicreference get+compareAndExchange,效率更高。

然后关于classfile api用途,一般创建classdesc是clazz.describeConstable().orElseThrow(),最好存static final,或者直接拿ConstantDescs里面的用;然后TypeKind有TypeKind.from(TypeDescriptor.OfField)可以直接接收Class。这样写起来会方便很多。

还是很喜欢作者这个实验项目的,因为能了解用户对classfile api和stable value的看法,对提升这两个API的用户体验有帮助。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions