首页 >Java >java教程 >Java 8 是否缓存方法引用以及何时应考虑缓存它们?

Java 8 是否缓存方法引用以及何时应考虑缓存它们?

Patricia Arquette
Patricia Arquette原创
2024-11-30 06:42:11779浏览

Does Java 8 Cache Method References and When Should You Consider Caching Them?

Java 8 中的方法引用缓存:详细检查

简介

使用时Java 8 的方法参考中,出现了一个关于缓存的潜在好处的问题。本文探讨了缓存方法引用的含义,并就其何时发挥优势提供了指导。

区分调用站点和方法引用执行

区分这一点至关重要使用无状态或有状态 lambda 频繁执行同一调用点,以及不同方法频繁使用对同一方法的方法引用之间call-sites.

示例分析

考虑以下示例:

Runnable r1 = null;
for (int i = 0; i < 2; i++) {
    Runnable r2 = System::gc;
    if (r1 == null) {
        r1 = r2;
    } else {
        System.out.println(r1 == r2 ? "shared" : "unshared");
    }
}

这里,同一个调用点被执行两次,产生无状态 lambda,实现将打印“共享”。

Runnable r1 = null;
for (int i = 0; i < 2; i++) {
    Runnable r2 = Runtime.getRuntime()::gc;
    if (r1 == null) {
        r1 = r2;
    } else {
        System.out.println(r1 == r2 ? "shared" : "unshared");
        System.out.println(r1.getClass() == r2.getClass() ? "shared class" : "unshared class");
    }
}

与在这个示例中,同一个调用站点被执行两次,生成一个包含对运行时实例的引用的 lambda,并且该实现将打印“unshared”但“shared class”。

Runnable r1 = System::gc, r2 = System::gc;
System.out.println(r1 == r2 ? "shared" : "unshared");
System.out.println(r1.getClass() == r2.getClass() ? "shared class" : "unshared class");

相反,最后一个示例包括两个单独的调用站点,生成等效的方法引用,但从 Java 8.0.05 开始,它将打印“unshared”和“unshared” class."

JVM 行为

Java 虚拟机 (JVM) 在处理方法引用方面发挥着重要作用。它使用invokedynamic指令,该指令引用LambdaMetafactory中的JRE引导方法。编译器提供生成 lambda 实现类所需的参数。

JVM 可以灵活地记住和重用第一次调用期间形成的 CallSite 实例。对于无状态 lambda 和单个调用站点,JVM 通常会创建一个 ConstantCallSite,其中包含常量对象的 MethodHandle。

另一方面,对于带有参数的 lambda(例如 this::func),JVM 可能会缓存它们,但它涉及维护参数和 lambda 实例之间的映射的额外开销。目前,JVM 不缓存此类 lambda。此行为类似于对不同调用站点创建的相同目标方法的方法引用。

缓存注意事项

基于上述几点,缓存方法引用可能会产生不同的结果,但不一定有更好的性能。在实施任何缓存机制之前应测量性能影响。在某些特定情况下,缓存可能会有所帮助:

  • 当多个调用点引用同一个方法时
  • 当在构造函数/类初始化中创建 lambda 时
  • 当使用点将由多个并发执行时线程
  • 当第一个 lambda 调用的较低性能是关注

结论

在某些场景下,缓存方法引用可以是一种优化技术。然而,缓存的决定应该基于对代码和具体性能要求的仔细分析。 JVM 对方法引用的处理为优化 Java 8 中的 lambda 和方法引用使用提供了坚实的基础。

以上是Java 8 是否缓存方法引用以及何时应考虑缓存它们?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn